<commit_before>//! Implements the HTTPMU and lower layers of the UPnP standard.
//!
//! This module deals with primitives for working with external libraries to write
//! data to UDP sockets as a stream, and read data from UDP sockets as packets.

use std::io::{self, Error, ErrorKind};
use std::net::{ToSocketAddrs, UdpSocket, SocketAddr, IpAddr, Ipv4Addr};
use std::mem;

use libc;

pub mod connector;
pub mod packet;
pub mod sender;

// I found that most of the fd's for UdpSockets were 32 bits but the UdpSockets
// themselves were 64 bits. I created a bunch of UdpSockets and looked at the
// bit representation of the value as a u64. All 32 of the upper bits in all
// of the sockets were set to the upper bits of 910533066752 so we need to
// OR our 32 bit socket with this number in order to cast to a UdpSocket.
const MUCH_MAGIC_NUMBER_WOW: u64 = 910533066752;

#[cfg(windows)]
type Socket = libc::SOCKET;

#[cfg(not(windows))]
type Socket = libc::c_int;

/// Accept a type implementing ToSocketAddrs and tries to extract the first address.
pub fn addr_from_trait<A: ToSocketAddrs>(addr: A) -> io::Result<SocketAddr> {
    let mut sock_iter = try!(addr.to_socket_addrs());

    match sock_iter.next() {
        Some(n) => Ok(n),
        None    => Err(io::Error::new(ErrorKind::InvalidInput, "Failed To Parse SocketAddr"))
    }
}

/// Bind to a UdpSocket, setting SO_REUSEADDR on the underlying socket before binding.
pub fn bind_reuse<A: ToSocketAddrs>(local_addr: A) -> io::Result<UdpSocket> {
    try!(init_sock_api());

    let local_addr = try!(addr_from_trait(local_addr));
    let udp_socket = try!(create_udp_socket(&local_addr));

    try!(reuse_addr(udp_socket));
    try!(bind_addr(udp_socket, &local_addr));

    let size_correction: u64 = MUCH_MAGIC_NUMBER_WOW | (udp_socket as u64);

    Ok(unsafe{ mem::transmute::<u64, UdpSocket>(size_correction) })
}

/// Join a multicast address on the current UdpSocket.
pub fn join_multicast(sock: &UdpSocket, iface_addr: &IpAddr, mcast_addr: &IpAddr)
    -> io::Result<()> {
    let (iface_ip, mcast_ip) = match (iface_addr, mcast_addr) {
        (&IpAddr::V4(ref i), &IpAddr::V4(ref m)) => (i, m),
        (&IpAddr::V6(..), &IpAddr::V6(..)) => {
            return Err(io::Error::new(ErrorKind::InvalidInput,
                "Ipv6Addr Multicast Not Currently Supported"))
        },
        _ => return Err(io::Error::new(ErrorKind::InvalidInput,
                 "Multicast And Interface Addresses Are Not The Same Version"))
    };
    let socket = unsafe{ mem::transmute_copy::<UdpSocket, Socket>(sock) };

    set_membership_ipv4(socket, iface_ip, mcast_ip, libc::IP_ADD_MEMBERSHIP)
}

#[allow(unused)]
/// Leave a multicast address on the current UdpSocket.
pub fn leave_multicast(sock: &UdpSocket, iface_addr: &IpAddr, mcast_addr: &IpAddr)
    -> io::Result<()> {
    let (iface_ip, mcast_ip) = match (iface_addr, mcast_addr) {
        (&IpAddr::V4(ref i), &IpAddr::V4(ref m)) => {
            (i, m)
        },
        (&IpAddr::V6(..), &IpAddr::V6(..)) => {
            return Err(io::Error::new(ErrorKind::InvalidInput,
                "Ipv6Addr Multicast Not Currently Supported"))
        },
        _ => return Err(io::Error::new(ErrorKind::InvalidInput,
                 "Multicast And Interface Addresses Are Not The Same Version"))
    };
    let socket = unsafe{ mem::transmute_copy::<UdpSocket, Socket>(sock) };

    set_membership_ipv4(socket, iface_ip, mcast_ip, libc::IP_DROP_MEMBERSHIP)
}

//----------------------------------------------------------------------------//

/// Run the initialization routine for the sockets API.
fn init_sock_api() -> io::Result<()> {
    // Since we do not have access to the socket initialization function in libstd,
    // we will have to create a UdpSocket so that it invokes that function for
    // our platform.
    let init_facade = UdpSocket::bind(("0.0.0.0", 0));

    init_facade.map(|_| ())
}

/// Create a socket that has been checked to be valid.
fn create_udp_socket(sock_addr: &SocketAddr) -> io::Result<Socket> {
    let family = match *sock_addr {
        SocketAddr::V4(..) => libc::AF_INET,
        SocketAddr::V6(..) => libc::AF_INET6
    };
    let socket = unsafe{ libc::socket(family, libc::SOCK_DGRAM, 0) };

    check_socket(socket).map(|_| socket)
}

/// Set SO_REUSEADDR option on the socket.
fn reuse_addr(socket: Socket) -> io::Result<()> {
    let opt: libc::c_int = 1;

    let ret = unsafe {
        libc::setsockopt(socket, libc::SOL_SOCKET, libc::SO_REUSEADDR,
            &opt as *const libc::c_int as *const libc::c_void,
            mem::size_of::<libc::c_int>() as libc::socklen_t)
    };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Bind the socket to the given socket address.
fn bind_addr(socket: Socket, sock_addr: &SocketAddr) -> io::Result<()> {
    let (sock_addr, sock_len) = match *sock_addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as libc::socklen_t)
        },
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as libc::socklen_t)
        }
    };

    let ret = unsafe{ libc::bind(socket, sock_addr, sock_len) };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Join the socket on the given interface to the given multicast address.
fn set_membership_ipv4(socket: Socket, iface_addr: &Ipv4Addr,
    mcast_addr: &Ipv4Addr, opt: libc::c_int) -> io::Result<()> {
    let mreq = libc::ip_mreq {
        imr_multiaddr: ipv4addr_as_in_addr(mcast_addr),
        imr_interface: ipv4addr_as_in_addr(iface_addr)
    };

    let ret = unsafe {
        libc::setsockopt(socket, libc::IPPROTO_IP, opt,
            &mreq as *const libc::ip_mreq as *const libc::c_void,
            mem::size_of::<libc::ip_mreq>() as libc::socklen_t)
    };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Convert the ipv4 address to a single number.
fn ipv4addr_as_in_addr(addr: &Ipv4Addr) -> libc::in_addr {
    unsafe{ mem::transmute_copy::<Ipv4Addr, libc::in_addr>(addr) }
}

/// Check The Return Value Of A Call To libc::socket().
#[cfg(windows)]
fn check_socket(sock: Socket) -> io::Result<()> {
    if sock == libc::INVALID_SOCKET {
        // Don't Have Access To Private Function WSAGetLastError()
        Err(Error::new(ErrorKind::Other, "Error With Socket Creation"))
    } else {
        Ok(())
    }
}

/// Check The Return Value Of A Call To libc::socket().
#[cfg(not(windows))]
fn check_socket(sock: Socket) -> io::Result<()> {
    if sock == -1i32 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn positive_addr_from_trait() {
        super::addr_from_trait("192.168.0.1:0").unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_addr_from_trait() {
        super::addr_from_trait("192.168.0.1").unwrap();
    }
}<commit_msg>Migrate from manual transmute into UdpSocket to FromRawSocket and FromRawFd<commit_after>//! Implements the HTTPMU and lower layers of the UPnP standard.
//!
//! This module deals with primitives for working with external libraries to write
//! data to UDP sockets as a stream, and read data from UDP sockets as packets.

use std::io::{self, Error, ErrorKind};
use std::net::{ToSocketAddrs, UdpSocket, SocketAddr, IpAddr, Ipv4Addr};
use std::mem;

#[cfg(windows)]
use std::os::windows::io::{RawSocket, FromRawSocket};

#[cfg(not(windows))]
use std::os::unix::io::{RawFd, FromRawFd};

use libc;

pub mod connector;
pub mod packet;
pub mod sender;

#[cfg(windows)]
type Socket = libc::SOCKET;

#[cfg(not(windows))]
type Socket = libc::c_int;

/// Accept a type implementing ToSocketAddrs and tries to extract the first address.
pub fn addr_from_trait<A: ToSocketAddrs>(addr: A) -> io::Result<SocketAddr> {
    let mut sock_iter = try!(addr.to_socket_addrs());

    match sock_iter.next() {
        Some(n) => Ok(n),
        None    => Err(io::Error::new(ErrorKind::InvalidInput, "Failed To Parse SocketAddr"))
    }
}

/// Bind to a UdpSocket, setting SO_REUSEADDR on the underlying socket before binding.
pub fn bind_reuse<A: ToSocketAddrs>(local_addr: A) -> io::Result<UdpSocket> {
    try!(init_sock_api());

    let local_addr = try!(addr_from_trait(local_addr));
    let socket = try!(create_udp_socket(&local_addr));

    try!(reuse_addr(socket));
    try!(bind_addr(socket, &local_addr));

    Ok(udp_socket_from_socket(socket))
}

/// Join a multicast address on the current UdpSocket.
pub fn join_multicast(sock: &UdpSocket, iface_addr: &IpAddr, mcast_addr: &IpAddr)
    -> io::Result<()> {
    let (iface_ip, mcast_ip) = match (iface_addr, mcast_addr) {
        (&IpAddr::V4(ref i), &IpAddr::V4(ref m)) => (i, m),
        (&IpAddr::V6(..), &IpAddr::V6(..)) => {
            return Err(io::Error::new(ErrorKind::InvalidInput,
                "Ipv6Addr Multicast Not Currently Supported"))
        },
        _ => return Err(io::Error::new(ErrorKind::InvalidInput,
                 "Multicast And Interface Addresses Are Not The Same Version"))
    };
    let socket = unsafe{ mem::transmute_copy::<UdpSocket, Socket>(sock) };

    set_membership_ipv4(socket, iface_ip, mcast_ip, libc::IP_ADD_MEMBERSHIP)
}

#[allow(unused)]
/// Leave a multicast address on the current UdpSocket.
pub fn leave_multicast(sock: &UdpSocket, iface_addr: &IpAddr, mcast_addr: &IpAddr)
    -> io::Result<()> {
    let (iface_ip, mcast_ip) = match (iface_addr, mcast_addr) {
        (&IpAddr::V4(ref i), &IpAddr::V4(ref m)) => {
            (i, m)
        },
        (&IpAddr::V6(..), &IpAddr::V6(..)) => {
            return Err(io::Error::new(ErrorKind::InvalidInput,
                "Ipv6Addr Multicast Not Currently Supported"))
        },
        _ => return Err(io::Error::new(ErrorKind::InvalidInput,
                 "Multicast And Interface Addresses Are Not The Same Version"))
    };
    let socket = unsafe{ mem::transmute_copy::<UdpSocket, Socket>(sock) };

    set_membership_ipv4(socket, iface_ip, mcast_ip, libc::IP_DROP_MEMBERSHIP)
}

//----------------------------------------------------------------------------//

/// Run the initialization routine for the sockets API.
fn init_sock_api() -> io::Result<()> {
    // Since we do not have access to the socket initialization function in libstd,
    // we will have to create a UdpSocket so that it invokes that function for
    // our platform.
    let init_facade = UdpSocket::bind(("0.0.0.0", 0));

    init_facade.map(|_| ())
}

/// Create a socket that has been checked to be valid.
fn create_udp_socket(sock_addr: &SocketAddr) -> io::Result<Socket> {
    let family = match *sock_addr {
        SocketAddr::V4(..) => libc::AF_INET,
        SocketAddr::V6(..) => libc::AF_INET6
    };
    let socket = unsafe{ libc::socket(family, libc::SOCK_DGRAM, 0) };

    check_socket(socket).map(|_| socket)
}

/// Set SO_REUSEADDR option on the socket.
fn reuse_addr(socket: Socket) -> io::Result<()> {
    let opt: libc::c_int = 1;

    let ret = unsafe {
        libc::setsockopt(socket, libc::SOL_SOCKET, libc::SO_REUSEADDR,
            &opt as *const libc::c_int as *const libc::c_void,
            mem::size_of::<libc::c_int>() as libc::socklen_t)
    };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Bind the socket to the given socket address.
fn bind_addr(socket: Socket, sock_addr: &SocketAddr) -> io::Result<()> {
    let (sock_addr, sock_len) = match *sock_addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as libc::socklen_t)
        },
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as libc::socklen_t)
        }
    };

    let ret = unsafe{ libc::bind(socket, sock_addr, sock_len) };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Join the socket on the given interface to the given multicast address.
fn set_membership_ipv4(socket: Socket, iface_addr: &Ipv4Addr,
    mcast_addr: &Ipv4Addr, opt: libc::c_int) -> io::Result<()> {
    let mreq = libc::ip_mreq {
        imr_multiaddr: ipv4addr_as_in_addr(mcast_addr),
        imr_interface: ipv4addr_as_in_addr(iface_addr)
    };

    let ret = unsafe {
        libc::setsockopt(socket, libc::IPPROTO_IP, opt,
            &mreq as *const libc::ip_mreq as *const libc::c_void,
            mem::size_of::<libc::ip_mreq>() as libc::socklen_t)
    };

    if ret != 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

/// Convert the ipv4 address to a single number.
fn ipv4addr_as_in_addr(addr: &Ipv4Addr) -> libc::in_addr {
    unsafe{ mem::transmute_copy::<Ipv4Addr, libc::in_addr>(addr) }
}

#[cfg(windows)]
fn udp_socket_from_socket(socket: Socket) -> UdpSocket {
    let raw_socket = unsafe{ mem::transmute::<Socket, RawSocket>(socket) };

    unsafe{ UdpSocket::from_raw_socket(raw_socket) }
}

#[cfg(not(windows))]
fn udp_socket_from_socket(socket: Socket) -> UdpSocket {
    let raw_fd = unsafe{ mem::transmute::<Socket, RawFd>(socket) };

    unsafe{ UdpSocket::from_raw_fd(raw_fd) }
}

/// Check The Return Value Of A Call To libc::socket().
#[cfg(windows)]
fn check_socket(sock: Socket) -> io::Result<()> {
    if sock == libc::INVALID_SOCKET {
        // Don't Have Access To Private Function WSAGetLastError()
        Err(Error::new(ErrorKind::Other, "Error With Socket Creation"))
    } else {
        Ok(())
    }
}

/// Check The Return Value Of A Call To libc::socket().
#[cfg(not(windows))]
fn check_socket(sock: Socket) -> io::Result<()> {
    if sock == -1i32 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn positive_addr_from_trait() {
        super::addr_from_trait("192.168.0.1:0").unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_addr_from_trait() {
        super::addr_from_trait("192.168.0.1").unwrap();
    }
}<|endoftext|>


<commit_before>use ::expr::Expr;

#[cfg(test)] mod spec;

#[derive(PartialEq,Clone,Debug)]
pub enum State {
    State{edge: char, out: Edge},
    Split{state1: State, state2: State}
}

enum Edge {
    Id(usize),
    Detached,
    End
}

impl State {
    pub fn state(edge: char, out: Edge) -> State {
        State::State{edge: edge, out: out}
    }

    pub fn split(state1: Edge, state2: Edge) -> State {
        State::Split{state1: state1,
                     state2: state2}
    }
}

struct NFA {
    states: Vec<State>
}

impl NFA {

    pub fn new() -> NFA {
        NFA {
            states: Vec::new()
        }
    }

    pub fn from_expr(expr: &Expr) -> NFA {
        let nfa = Self::new();

        let id = nfa.build_expr(expr);
        nfa.update_outputs(id, State::End);
        nfa
    }

    fn build_expr(&mut self, expr: &Expr) -> usize {
        let id = match expr {
            &Expr::Single(c) => {
                let new_state_id = self.states.len();
                let s = State::state(c, new_state_id + 1);
                self.states.push(s);
                self.states.push(State::Detached);
                self.states.len() - 1
            },
            &Expr::Sequence(ref a, ref b) => {
                let left_id = self.build_expr(&*a);
                let right_id = self.build_expr(&*b);
                self.update_outputs(left_id, right_id);
                left_id
            },
            _ => panic!()
        };

        id
    }

    fn update_outputs(self, start_id: usize, new_id: usize) {
        let state = match self.states[start_id] {
            State::State{edge, out} => {
                State::state(edge,
                             match self.states[out] {
                                 State::Detached => {
                                     new_id
                                 },
                                 _ => {
                                     self.update_outputs(out, new_id);
                                     out
                                 }
                             })
            },
            _ => self.states[start_id]
        };
    }
}

<commit_msg>rustc runs out of memory?<commit_after>use ::expr::Expr;

#[cfg(test)] mod spec;

#[derive(PartialEq,Clone,Debug)]
pub enum State {
    State{edge: char, out: Edge},
    Split{state1: State, state2: State}
}

enum Edge {
    Id(usize),
    Detached,
    End
}

impl State {
    pub fn state(edge: char, out: Edge) -> State {
        State::State{edge: edge, out: out}
    }

    pub fn split(state1: Edge, state2: Edge) -> State {
        State::Split{state1: state1,
                     state2: state2}
    }
}

struct NFA {
    states: Vec<State>
}

impl NFA {

    pub fn new() -> NFA {
        NFA {
            states: Vec::new()
        }
    }

    pub fn from_expr(expr: &Expr) -> NFA {
        let nfa = Self::new();

        let id = nfa.build_expr(expr);
        nfa.update_outputs(id, State::End);
        nfa
    }

    fn build_expr(&mut self, expr: &Expr) -> usize {
        let id = match expr {
            &Expr::Single(c) => {
                let new_state_id = self.states.len();
                let s = State::state(c, new_state_id + 1);
                self.states.push(s);
                self.states.push(State::Detached);
                self.states.len() - 1
            },
            &Expr::Sequence(ref a, ref b) => {
                let left_id = self.build_expr(&*a);
                let right_id = self.build_expr(&*b);
                self.update_outputs(left_id, right_id);
                left_id
            },
            _ => panic!()
        };

        id
    }

    fn update_outputs(self, start_id: usize, new_id: usize) {

        let state = match self.states[start_id] {
            State::State{edge, out} => {
                State::state(edge,
                             match self.states[out] {
                                 State::Detached => {
                                     new_id
                                 },
                                 _ => {
                                     self.update_outputs(out, new_id);
                                     out
                                 }
                             })
            },
            _ => self.states[start_id]
        };
    }
}

<|endoftext|>


<commit_before>use clap::ArgMatches;
use std::default::Default;

#[derive(Debug)]
pub struct SkimOptions<'a> {
    pub bind: Vec<&'a str>,
    pub multi: bool,
    pub prompt: Option<&'a str>,
    pub cmd_prompt: Option<&'a str>,
    pub expect: Option<String>,
    pub tac: bool,
    pub tiebreak: Option<String>,
    pub ansi: bool,
    pub exact: bool,
    pub cmd: Option<&'a str>,
    pub interactive: bool,
    pub query: Option<&'a str>,
    pub cmd_query: Option<&'a str>,
    pub regex: bool,
    pub delimiter: Option<&'a str>,
    pub nth: Option<&'a str>,
    pub with_nth: Option<&'a str>,
    pub replstr: Option<&'a str>,
    pub color: Option<&'a str>,
    pub margin: Option<&'a str>,
    pub min_height: Option<&'a str>,
    pub height: Option<&'a str>,
    pub preview: Option<&'a str>,
    pub preview_window: Option<&'a str>,
    pub reverse: bool,
    pub read0: bool,
    pub print0: bool,
    pub tabstop: Option<&'a str>,
    pub print_query: bool,
    pub print_cmd: bool,
    pub no_hscroll: bool,
    pub inline_info: bool
}

impl<'a> SkimOptions<'a> {
    pub fn from_options(options: &'a ArgMatches) -> SkimOptions<'a> {
        let color = options.values_of("color").and_then(|vals| vals.last());
        let min_height = options.values_of("min-height").and_then(|vals| vals.last());
        let no_height = options.is_present("no-height");
        let height = if no_height {
            Some("100%")
        } else {
            options.values_of("height").and_then(|vals| vals.last())
        };
        let margin = options.values_of("margin").and_then(|vals| vals.last());
        let preview = options.values_of("preview").and_then(|vals| vals.last());
        let preview_window = options.values_of("preview-window").and_then(|vals| vals.last());

        let cmd = options.values_of("cmd").and_then(|vals| vals.last());
        let query = options.values_of("query").and_then(|vals| vals.last());
        let cmd_query = options.values_of("cmd-query").and_then(|vals| vals.last());
        let replstr = options.values_of("replstr").and_then(|vals| vals.last());
        let interactive = options.is_present("interactive");
        let prompt = options.values_of("prompt").and_then(|vals| vals.last());
        let cmd_prompt = options.values_of("cmd-prompt").and_then(|vals| vals.last());

        let ansi = options.is_present("ansi");
        let delimiter = options.values_of("delimiter").and_then(|vals| vals.last());
        let with_nth = options.values_of("with-nth").and_then(|vals| vals.last());
        let nth = options.values_of("nth").and_then(|vals| vals.last());
        let read0 = options.is_present("read0");

        let bind = options
            .values_of("bind")
            .map(|x| x.collect::<Vec<_>>())
            .unwrap_or_default();
        let expect = options.values_of("expect").map(|x| x.collect::<Vec<_>>().join(","));

        let multi = options.is_present("multi");
        let no_multi = options.is_present("no-multi");
        let reverse = options.is_present("reverse");
        let print0 = options.is_present("print0");
        let print_query = options.is_present("print-query");
        let print_cmd = options.is_present("print-cmd");
        let no_hscroll = options.is_present("no-hscroll");
        let tabstop = options.values_of("tabstop").and_then(|vals| vals.last());

        let tiebreak = options.values_of("tiebreak").map(|x| x.collect::<Vec<_>>().join(","));
        let tac = options.is_present("tac");
        let exact = options.is_present("exact");
        let regex = options.is_present("regex");
        let inline_info = options.is_present("inline-info");

        SkimOptions {
            color,
            min_height,
            height,
            margin,
            preview,
            preview_window,
            cmd,
            query,
            cmd_query,
            replstr,
            interactive,
            prompt,
            cmd_prompt,
            ansi,
            delimiter,
            with_nth,
            nth,
            read0,
            bind,
            expect,
            multi: !no_multi && multi,
            reverse,
            print_query,
            print_cmd,
            print0,
            no_hscroll,
            tabstop,
            tiebreak,
            tac,
            exact,
            regex,
            inline_info
        }
    }

    pub fn bind(self, bind: Vec<&'a str>) -> Self {
        Self { bind, ..self }
    }
    pub fn multi(self, multi: bool) -> Self {
        Self { multi, ..self }
    }
    pub fn prompt(self, prompt: &'a str) -> Self {
        Self {
            prompt: Some(prompt),
            ..self
        }
    }
    pub fn cmd_prompt(self, cmd_prompt: &'a str) -> Self {
        Self {
            cmd_prompt: Some(cmd_prompt),
            ..self
        }
    }
    pub fn expect(self, expect: String) -> Self {
        Self {
            expect: Some(expect),
            ..self
        }
    }
    pub fn tac(self, tac: bool) -> Self {
        Self { tac, ..self }
    }
    pub fn tiebreak(self, tiebreak: String) -> Self {
        Self {
            tiebreak: Some(tiebreak),
            ..self
        }
    }
    pub fn ansi(self, ansi: bool) -> Self {
        Self { ansi, ..self }
    }
    pub fn exact(self, exact: bool) -> Self {
        Self { exact, ..self }
    }
    pub fn cmd(self, cmd: &'a str) -> Self {
        Self { cmd: Some(cmd), ..self }
    }
    pub fn interactive(self, interactive: bool) -> Self {
        Self { interactive, ..self }
    }
    pub fn query(self, query: &'a str) -> Self {
        Self {
            query: Some(query),
            ..self
        }
    }
    pub fn cmd_query(self, cmd_query: &'a str) -> Self {
        Self {
            cmd_query: Some(cmd_query),
            ..self
        }
    }
    pub fn regex(self, regex: bool) -> Self {
        Self { regex, ..self }
    }
    pub fn delimiter(self, delimiter: &'a str) -> Self {
        Self {
            delimiter: Some(delimiter),
            ..self
        }
    }
    pub fn nth(self, nth: &'a str) -> Self {
        Self { nth: Some(nth), ..self }
    }
    pub fn with_nth(self, with_nth: &'a str) -> Self {
        Self {
            with_nth: Some(with_nth),
            ..self
        }
    }
    pub fn replstr(self, replstr: &'a str) -> Self {
        Self {
            replstr: Some(replstr),
            ..self
        }
    }
    pub fn color(self, color: &'a str) -> Self {
        Self {
            color: Some(color),
            ..self
        }
    }
    pub fn margin(self, margin: &'a str) -> Self {
        Self {
            margin: Some(margin),
            ..self
        }
    }
    pub fn min_height(self, min_height: &'a str) -> Self {
        Self {
            min_height: Some(min_height),
            ..self
        }
    }
    pub fn height(self, height: &'a str) -> Self {
        Self {
            height: Some(height),
            ..self
        }
    }
    pub fn preview(self, preview: &'a str) -> Self {
        Self {
            preview: Some(preview),
            ..self
        }
    }
    pub fn preview_window(self, preview_window: &'a str) -> Self {
        Self {
            preview_window: Some(preview_window),
            ..self
        }
    }
    pub fn reverse(self, reverse: bool) -> Self {
        Self { reverse, ..self }
    }
    pub fn read0(self, read0: bool) -> Self {
        Self { read0, ..self }
    }
    pub fn print0(self, print0: bool) -> Self {
        Self { print0, ..self }
    }
    pub fn tabstop(self, tabstop: &'a str) -> Self {
        Self {
            tabstop: Some(tabstop),
            ..self
        }
    }
    pub fn print_query(self, print_query: bool) -> Self {
        Self { print_query, ..self }
    }
    pub fn print_cmd(self, print_cmd: bool) -> Self {
        Self { print_cmd, ..self }
    }
    pub fn no_hscroll(self, no_hscroll: bool) -> Self {
        Self { no_hscroll, ..self }
    }
}

impl<'a> Default for SkimOptions<'a> {
    fn default() -> SkimOptions<'a> {
        SkimOptions {
            bind: Vec::new(),
            multi: false,
            prompt: Some("> "),
            cmd_prompt: Some("c> "),
            expect: None,
            tac: false,
            tiebreak: None,
            ansi: false,
            exact: false,
            cmd: None,
            interactive: false,
            query: None,
            cmd_query: None,
            regex: false,
            delimiter: None,
            nth: None,
            with_nth: None,
            replstr: Some("{}"),
            color: None,
            margin: Some("0,0,0,0"),
            min_height: Some("10"),
            height: Some("100%"),
            preview: None,
            preview_window: Some("right:50%"),
            reverse: false,
            read0: false,
            print0: false,
            tabstop: None,
            print_query: false,
            print_cmd: false,
            no_hscroll: false,
            inline_info: false
        }
    }
}
<commit_msg>Add inline_info function to options<commit_after>use clap::ArgMatches;
use std::default::Default;

#[derive(Debug)]
pub struct SkimOptions<'a> {
    pub bind: Vec<&'a str>,
    pub multi: bool,
    pub prompt: Option<&'a str>,
    pub cmd_prompt: Option<&'a str>,
    pub expect: Option<String>,
    pub tac: bool,
    pub tiebreak: Option<String>,
    pub ansi: bool,
    pub exact: bool,
    pub cmd: Option<&'a str>,
    pub interactive: bool,
    pub query: Option<&'a str>,
    pub cmd_query: Option<&'a str>,
    pub regex: bool,
    pub delimiter: Option<&'a str>,
    pub nth: Option<&'a str>,
    pub with_nth: Option<&'a str>,
    pub replstr: Option<&'a str>,
    pub color: Option<&'a str>,
    pub margin: Option<&'a str>,
    pub min_height: Option<&'a str>,
    pub height: Option<&'a str>,
    pub preview: Option<&'a str>,
    pub preview_window: Option<&'a str>,
    pub reverse: bool,
    pub read0: bool,
    pub print0: bool,
    pub tabstop: Option<&'a str>,
    pub print_query: bool,
    pub print_cmd: bool,
    pub no_hscroll: bool,
    pub inline_info: bool
}

impl<'a> SkimOptions<'a> {
    pub fn from_options(options: &'a ArgMatches) -> SkimOptions<'a> {
        let color = options.values_of("color").and_then(|vals| vals.last());
        let min_height = options.values_of("min-height").and_then(|vals| vals.last());
        let no_height = options.is_present("no-height");
        let height = if no_height {
            Some("100%")
        } else {
            options.values_of("height").and_then(|vals| vals.last())
        };
        let margin = options.values_of("margin").and_then(|vals| vals.last());
        let preview = options.values_of("preview").and_then(|vals| vals.last());
        let preview_window = options.values_of("preview-window").and_then(|vals| vals.last());

        let cmd = options.values_of("cmd").and_then(|vals| vals.last());
        let query = options.values_of("query").and_then(|vals| vals.last());
        let cmd_query = options.values_of("cmd-query").and_then(|vals| vals.last());
        let replstr = options.values_of("replstr").and_then(|vals| vals.last());
        let interactive = options.is_present("interactive");
        let prompt = options.values_of("prompt").and_then(|vals| vals.last());
        let cmd_prompt = options.values_of("cmd-prompt").and_then(|vals| vals.last());

        let ansi = options.is_present("ansi");
        let delimiter = options.values_of("delimiter").and_then(|vals| vals.last());
        let with_nth = options.values_of("with-nth").and_then(|vals| vals.last());
        let nth = options.values_of("nth").and_then(|vals| vals.last());
        let read0 = options.is_present("read0");

        let bind = options
            .values_of("bind")
            .map(|x| x.collect::<Vec<_>>())
            .unwrap_or_default();
        let expect = options.values_of("expect").map(|x| x.collect::<Vec<_>>().join(","));

        let multi = options.is_present("multi");
        let no_multi = options.is_present("no-multi");
        let reverse = options.is_present("reverse");
        let print0 = options.is_present("print0");
        let print_query = options.is_present("print-query");
        let print_cmd = options.is_present("print-cmd");
        let no_hscroll = options.is_present("no-hscroll");
        let tabstop = options.values_of("tabstop").and_then(|vals| vals.last());

        let tiebreak = options.values_of("tiebreak").map(|x| x.collect::<Vec<_>>().join(","));
        let tac = options.is_present("tac");
        let exact = options.is_present("exact");
        let regex = options.is_present("regex");
        let inline_info = options.is_present("inline-info");

        SkimOptions {
            color,
            min_height,
            height,
            margin,
            preview,
            preview_window,
            cmd,
            query,
            cmd_query,
            replstr,
            interactive,
            prompt,
            cmd_prompt,
            ansi,
            delimiter,
            with_nth,
            nth,
            read0,
            bind,
            expect,
            multi: !no_multi && multi,
            reverse,
            print_query,
            print_cmd,
            print0,
            no_hscroll,
            tabstop,
            tiebreak,
            tac,
            exact,
            regex,
            inline_info
        }
    }

    pub fn bind(self, bind: Vec<&'a str>) -> Self {
        Self { bind, ..self }
    }
    pub fn multi(self, multi: bool) -> Self {
        Self { multi, ..self }
    }
    pub fn prompt(self, prompt: &'a str) -> Self {
        Self {
            prompt: Some(prompt),
            ..self
        }
    }
    pub fn cmd_prompt(self, cmd_prompt: &'a str) -> Self {
        Self {
            cmd_prompt: Some(cmd_prompt),
            ..self
        }
    }
    pub fn expect(self, expect: String) -> Self {
        Self {
            expect: Some(expect),
            ..self
        }
    }
    pub fn tac(self, tac: bool) -> Self {
        Self { tac, ..self }
    }
    pub fn tiebreak(self, tiebreak: String) -> Self {
        Self {
            tiebreak: Some(tiebreak),
            ..self
        }
    }
    pub fn ansi(self, ansi: bool) -> Self {
        Self { ansi, ..self }
    }
    pub fn exact(self, exact: bool) -> Self {
        Self { exact, ..self }
    }
    pub fn cmd(self, cmd: &'a str) -> Self {
        Self { cmd: Some(cmd), ..self }
    }
    pub fn interactive(self, interactive: bool) -> Self {
        Self { interactive, ..self }
    }
    pub fn query(self, query: &'a str) -> Self {
        Self {
            query: Some(query),
            ..self
        }
    }
    pub fn cmd_query(self, cmd_query: &'a str) -> Self {
        Self {
            cmd_query: Some(cmd_query),
            ..self
        }
    }
    pub fn regex(self, regex: bool) -> Self {
        Self { regex, ..self }
    }
    pub fn delimiter(self, delimiter: &'a str) -> Self {
        Self {
            delimiter: Some(delimiter),
            ..self
        }
    }
    pub fn nth(self, nth: &'a str) -> Self {
        Self { nth: Some(nth), ..self }
    }
    pub fn with_nth(self, with_nth: &'a str) -> Self {
        Self {
            with_nth: Some(with_nth),
            ..self
        }
    }
    pub fn replstr(self, replstr: &'a str) -> Self {
        Self {
            replstr: Some(replstr),
            ..self
        }
    }
    pub fn color(self, color: &'a str) -> Self {
        Self {
            color: Some(color),
            ..self
        }
    }
    pub fn margin(self, margin: &'a str) -> Self {
        Self {
            margin: Some(margin),
            ..self
        }
    }
    pub fn min_height(self, min_height: &'a str) -> Self {
        Self {
            min_height: Some(min_height),
            ..self
        }
    }
    pub fn height(self, height: &'a str) -> Self {
        Self {
            height: Some(height),
            ..self
        }
    }
    pub fn preview(self, preview: &'a str) -> Self {
        Self {
            preview: Some(preview),
            ..self
        }
    }
    pub fn preview_window(self, preview_window: &'a str) -> Self {
        Self {
            preview_window: Some(preview_window),
            ..self
        }
    }
    pub fn reverse(self, reverse: bool) -> Self {
        Self { reverse, ..self }
    }
    pub fn read0(self, read0: bool) -> Self {
        Self { read0, ..self }
    }
    pub fn print0(self, print0: bool) -> Self {
        Self { print0, ..self }
    }
    pub fn tabstop(self, tabstop: &'a str) -> Self {
        Self {
            tabstop: Some(tabstop),
            ..self
        }
    }
    pub fn print_query(self, print_query: bool) -> Self {
        Self { print_query, ..self }
    }
    pub fn print_cmd(self, print_cmd: bool) -> Self {
        Self { print_cmd, ..self }
    }
    pub fn no_hscroll(self, no_hscroll: bool) -> Self {
        Self { no_hscroll, ..self }
    }
    pub fn inline_info(self, inline_info: bool) -> Self {
        Self { inline_info, ..self }
    }
}

impl<'a> Default for SkimOptions<'a> {
    fn default() -> SkimOptions<'a> {
        SkimOptions {
            bind: Vec::new(),
            multi: false,
            prompt: Some("> "),
            cmd_prompt: Some("c> "),
            expect: None,
            tac: false,
            tiebreak: None,
            ansi: false,
            exact: false,
            cmd: None,
            interactive: false,
            query: None,
            cmd_query: None,
            regex: false,
            delimiter: None,
            nth: None,
            with_nth: None,
            replstr: Some("{}"),
            color: None,
            margin: Some("0,0,0,0"),
            min_height: Some("10"),
            height: Some("100%"),
            preview: None,
            preview_window: Some("right:50%"),
            reverse: false,
            read0: false,
            print0: false,
            tabstop: None,
            print_query: false,
            print_cmd: false,
            no_hscroll: false,
            inline_info: false
        }
    }
}
<|endoftext|>


<commit_before>use luminance::blending::{Equation, Factor};
use luminance::framebuffer::Framebuffer;
use luminance::pipeline::{Pipeline, RenderCommand, ShadingCommand};
use luminance::tess::{Mode, Tess, TessRender, TessVertices};
use luminance::texture::{Dim2, Flat, Unit};
use luminance::vertex::{Vertex, VertexFormat};
use std::cell::RefCell;

use compositing::{ColorMap, DepthMap};
use framebuffer::Framebuffer2D;
use resource::{Res, ResCache};
use shader::{Program, Uniform};
use text::TextTexture;
use texture::{RGBA32F, Texture};

/// Vertex used in overlay’s objects. Position coordinates are in *window space*.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Vert {
  /// Position.
  pub pos: [f32; 3],
  /// Color.
  pub color: [f32; 4]
}

impl Vert {
  pub fn new(pos: [f32; 3], color: [f32; 4]) -> Self {
    Vert {
      pos: pos,
      color: color
    }
  }

  /// Convert the vertex’ position to *clip space*.
  ///
  /// > Note: the depth coordinate is not affected.
  fn to_clip_space(&self, converter: &UnitConverter) -> Self {
    let converted = converter.from_win_coord(self.pos[0], self.pos[1]);
    let pos_ = [converted[0], converted[1], self.pos[2]];

    Vert {
      pos: pos_,
      color: self.color
    }
  }
}

impl Vertex for Vert {
  fn vertex_format() -> VertexFormat {
    <([f32; 3], [f32; 4]) as Vertex>::vertex_format()
  }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Triangle(pub Vert, pub Vert, pub Vert);

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Quad(pub Vert, pub Vert, pub Vert, pub Vert);

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Disc {
  pub center: Vert,
  pub radius: f32
}

impl Disc {
  pub fn new(center: Vert, radius: f32) -> Self {
    Disc {
      center: center,
      radius: radius
    }
  }

  fn to_clip_space(&self, converter: &UnitConverter) -> Self {
    Disc {
      center: self.center.to_clip_space(converter),
      radius: self.radius * converter.rw
    }
  }
}

impl Vertex for Disc {
  fn vertex_format() -> VertexFormat {
    <(Vert, f32) as Vertex>::vertex_format()
  }
}

pub type Texture2D = Texture<Flat, Dim2, RGBA32F>;

#[derive(Copy, Clone)]
pub struct Text<'a> {
  text_texture: &'a TextTexture,
  left_lower: Vert
}

impl<'a> Text<'a> {
  pub fn new(text_texture: &'a TextTexture, left_lower: Vert) -> Self {
    Text {
      text_texture: text_texture,
      left_lower: left_lower
    }
  }
}

const DISC_SCREEN_RATIO: &'static Uniform<f32> = &Uniform::new(0);

const TEXT_SAMPLER: &'static Uniform<Unit> = &Uniform::new(0);
const TEXT_POS: &'static Uniform<[f32; 3]> = &Uniform::new(1);
const TEXT_SIZE: &'static Uniform<[f32; 2]> = &Uniform::new(2);
const TEXT_SCALE: &'static Uniform<f32> = &Uniform::new(3);
const TEXT_COLOR: &'static Uniform<[f32; 4]> = &Uniform::new(4);

pub struct Overlay {
  ratio: f32,
  tri_program: Res<Program>,
  tris: RefCell<Tess>,
  disc_program: Res<Program>,
  discs: RefCell<Tess>,
  text_program: Res<Program>,
  text_quad: Tess,
  unit_converter: UnitConverter,
}

impl Overlay {
  pub fn new(w: u32, h: u32, max_tris: usize, max_quads: usize, max_discs: usize, cache: &mut ResCache) -> Self {
    let tri_program = cache.get("spectra/overlay/triangle.glsl", vec![]).unwrap();
    let tris = Tess::new(Mode::Triangle, TessVertices::Reserve::<Vert>(max_tris * 3 + max_quads * 4), None);

    let disc_program = cache.get("spectra/overlay/disc.glsl", vec![DISC_SCREEN_RATIO.sem("ratio")]).unwrap();
    let discs = Tess::new(Mode::Point, TessVertices::Reserve::<Disc>(max_discs), None);

    let text_program = cache.get("spectra/overlay/text.glsl", vec![
      TEXT_SAMPLER.sem("text_texture"),
      TEXT_POS.sem("pos"),
      TEXT_SIZE.sem("size"),
      TEXT_SCALE.sem("scale"),
      TEXT_COLOR.sem("color")
    ]).unwrap();

    let text_quad = Tess::attributeless(Mode::TriangleStrip, 4);

    Overlay {
      ratio: w as f32 / h as f32,
      tri_program: tri_program,
      tris: RefCell::new(tris),
      disc_program: disc_program,
      discs: RefCell::new(discs),
      text_program: text_program,
      text_quad: text_quad,
      unit_converter: UnitConverter::new(w, h)
    }
  }

  /// Dispatch render input primitives into GPU buffers.
  fn dispatch(&self, input: &RenderInput) -> (usize, usize) {
    let mut tris_ref = self.tris.borrow_mut();
    let mut tris = tris_ref.as_slice_mut().unwrap();
    let mut tri_i = 0;

    let mut discs_ref = self.discs.borrow_mut();
    let mut discs = discs_ref.as_slice_mut().unwrap();
    let mut disc_i = 0;

    for &Triangle(a, b, c) in input.triangles {
      let abc = [a, b, c];

      for &v in &abc {
        tris[tri_i] = v.to_clip_space(&self.unit_converter);
        tri_i += 1;
      }
    }

    for &Quad(a, b, c, d) in input.quads {
      let abcd = [a, b, c, c, b, d];

      for &v in &abcd {
        tris[tri_i] = v.to_clip_space(&self.unit_converter);
        tri_i += 1;
      }
    }

    for disc in input.discs {
      discs[disc_i] = disc.to_clip_space(&self.unit_converter);
      disc_i += 1;
    }

    (tri_i, disc_i)
  }

  pub fn render(&self, framebuffer: &Framebuffer2D<ColorMap, DepthMap>, input: &RenderInput) {
    let (tri_vert_nb, disc_vert_nb) = self.dispatch(input);

    let tris_ref = self.tris.borrow();
    let tris = TessRender::one_sub(&tris_ref, tri_vert_nb);

    let discs_ref = self.discs.borrow();
    let discs = TessRender::one_sub(&discs_ref, disc_vert_nb);

    let text_quad = TessRender::one_whole(&self.text_quad);

    let tri_program = self.tri_program.borrow();
    let disc_program = self.disc_program.borrow();
    let text_program = self.text_program.borrow();

    Pipeline::new(framebuffer, [0., 0., 0., 0.], &[], &[]).enter(|shd_gate| {
      shd_gate.new(&tri_program, &[], &[], &[]).enter(|rdr_gate| {
        rdr_gate.new(None, true, &[], &[], &[]).enter(|tess_gate| {
          tess_gate.render(tris, &[], &[], &[]);
        });
      });

      shd_gate.new(&disc_program, &[DISC_SCREEN_RATIO.alter(self.ratio)], &[], &[]).enter(|rdr_gate| {
        rdr_gate.new(None, true, &[], &[], &[]).enter(|tess_gate| {
          tess_gate.render(discs, &[], &[], &[]);
        });
      });

      shd_gate.new(&text_program, &[], &[], &[]).enter(|rdr_gate| {
        for (text, text_scale) in input.texts {
          let blending = (Equation::Additive, Factor::One, Factor::SrcAlphaComplement);
          let (tex_w, tex_h) = text.text_texture.size();
          let uniforms = [
            TEXT_SAMPLER.alter(Unit::new(0)),
            TEXT_POS.alter(text.left_lower.to_clip_space(&self.unit_converter).pos),
            TEXT_SIZE.alter(self.unit_converter.from_win_dim(tex_w as f32, tex_h as f32)),
            TEXT_SCALE.alter(text_scale),
            TEXT_COLOR.alter(text.left_lower.color),
          ];

          rdr_gate.new(blending, true, &uniforms, &[&***text.text_texture], &[]).enter(|tess_gate| {
            tess_gate.render(text_quad.clone(), &[], &[], &[]);
          });
        }
      });
    });
  }
}

#[derive(Clone)]
pub struct RenderInput<'a> {
  triangles: &'a [Triangle],
  quads: &'a [Quad],
  discs: &'a [Disc],
  texts: Option<(&'a [Text<'a>], f32)>
}

impl<'a> RenderInput<'a> {
  pub fn new() -> Self {
    RenderInput {
      triangles: &[],
      quads: &[],
      discs: &[],
      texts: None,
    }
  }

  pub fn triangles(self, triangles: &'a [Triangle]) -> Self {
    RenderInput {
      triangles: triangles,
      ..self
    }
  }

  pub fn quads(self, quads: &'a [Quad]) -> Self {
    RenderInput {
      quads: quads,
      ..self
    }
  }

  pub fn discs(self, discs: &'a [Disc]) -> Self {
    RenderInput {
      discs: discs,
      ..self
    }
  }

  pub fn texts(self, texts: &'a [Text<'a>], scale: f32) -> Self {
    RenderInput {
      texts: Some((texts, scale.max(0.))),
      ..self
    }
  }
}

/// A *unit converter* is used to position stuff in overlay in a universal and screen independent
/// way.
///
/// The idea is that you provide should handle *window space* coordinates only. This type will then
/// help compute normalized coordinates the renderer can understand.
///
/// For the record, *window space* coordinates are defined as below – given a viewport size of
/// *w × h*:
///
/// ^ y = h
/// |
/// |
/// |    x = w
/// O------>
///
/// The formula used to convert from *window space* to what we call *clip space* is:
///
/// > x' = 2x / w - 1
/// > y' = 2y / h - 1
#[derive(Copy, Clone, Debug, PartialEq)]
struct UnitConverter {
  rw: f32,
  rh: f32,
  twice_rw: f32,
  twice_rh: f32
}

impl UnitConverter {
  /// Build a unit converter by giving it the size of the viewport.
  pub fn new(w: u32, h: u32) -> Self {
    let rw = 1. / (w as f32);
    let rh = 1. / (h as f32);

    UnitConverter {
      rw: rw,
      rh: rh,
      twice_rw: 2. * rw,
      twice_rh: 2. * rh
    }
  }

  /// Convert from *window space* coordinates to clip space* ones.
  pub fn from_win_coord(&self, x: f32, y: f32) -> [f32; 2] {
    let x_ = x * self.twice_rw - 1.;
    let y_ = y * self.twice_rh - 1.;

    [x_.min(1.).max(-1.), y_.min(1.).max(-1.)]
  }

  /// Convert from *window space* dimensions to clip space* ones.
  pub fn from_win_dim(&self, w: f32, h: f32) -> [f32; 2] {
    let w_ = w * self.rw;
    let h_ = h * self.rh;

    [w_.min(1.).max(-1.), h_.min(1.).max(-1.)]
  }
}
<commit_msg>Fixed overlay.<commit_after>use luminance::blending::{Equation, Factor};
use luminance::framebuffer::Framebuffer;
use luminance::pipeline::{Pipeline, RenderCommand, ShadingCommand};
use luminance::tess::{Mode, Tess, TessRender, TessVertices};
use luminance::texture::{Dim2, Flat, Unit};
use luminance::vertex::{Vertex, VertexFormat};
use std::cell::RefCell;

use compositing::{ColorMap, DepthMap};
use framebuffer::Framebuffer2D;
use resource::{Res, ResCache};
use shader::{Program, Uniform};
use text::TextTexture;
use texture::{RGBA32F, Texture};

/// Vertex used in overlay’s objects. Position coordinates are in *window space*.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Vert {
  /// Position.
  pub pos: [f32; 3],
  /// Color.
  pub color: [f32; 4]
}

impl Vert {
  pub fn new(pos: [f32; 3], color: [f32; 4]) -> Self {
    Vert {
      pos: pos,
      color: color
    }
  }

  /// Convert the vertex’ position to *clip space*.
  ///
  /// > Note: the depth coordinate is not affected.
  fn to_clip_space(&self, converter: &UnitConverter) -> Self {
    let converted = converter.from_win_coord(self.pos[0], self.pos[1]);
    let pos_ = [converted[0], converted[1], self.pos[2]];

    Vert {
      pos: pos_,
      color: self.color
    }
  }
}

impl Vertex for Vert {
  fn vertex_format() -> VertexFormat {
    <([f32; 3], [f32; 4]) as Vertex>::vertex_format()
  }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Triangle(pub Vert, pub Vert, pub Vert);

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Quad(pub Vert, pub Vert, pub Vert, pub Vert);

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Disc {
  pub center: Vert,
  pub radius: f32
}

impl Disc {
  pub fn new(center: Vert, radius: f32) -> Self {
    Disc {
      center: center,
      radius: radius
    }
  }

  fn to_clip_space(&self, converter: &UnitConverter) -> Self {
    Disc {
      center: self.center.to_clip_space(converter),
      radius: self.radius * converter.rw
    }
  }
}

impl Vertex for Disc {
  fn vertex_format() -> VertexFormat {
    <(Vert, f32) as Vertex>::vertex_format()
  }
}

pub type Texture2D = Texture<Flat, Dim2, RGBA32F>;

#[derive(Copy, Clone)]
pub struct Text<'a> {
  text_texture: &'a TextTexture,
  left_lower: Vert
}

impl<'a> Text<'a> {
  pub fn new(text_texture: &'a TextTexture, left_lower: Vert) -> Self {
    Text {
      text_texture: text_texture,
      left_lower: left_lower
    }
  }
}

const DISC_SCREEN_RATIO: &'static Uniform<f32> = &Uniform::new(0);

const TEXT_SAMPLER: &'static Uniform<Unit> = &Uniform::new(0);
const TEXT_POS: &'static Uniform<[f32; 3]> = &Uniform::new(1);
const TEXT_SIZE: &'static Uniform<[f32; 2]> = &Uniform::new(2);
const TEXT_SCALE: &'static Uniform<f32> = &Uniform::new(3);
const TEXT_COLOR: &'static Uniform<[f32; 4]> = &Uniform::new(4);

pub struct Overlay {
  ratio: f32,
  tri_program: Res<Program>,
  tris: RefCell<Tess>,
  disc_program: Res<Program>,
  discs: RefCell<Tess>,
  text_program: Res<Program>,
  text_quad: Tess,
  unit_converter: UnitConverter,
}

impl Overlay {
  pub fn new(w: u32, h: u32, max_tris: usize, max_quads: usize, max_discs: usize, cache: &mut ResCache) -> Self {
    let tri_program = cache.get("spectra/overlay/triangle.glsl", vec![]).unwrap();
    let tris = Tess::new(Mode::Triangle, TessVertices::Reserve::<Vert>(max_tris * 3 + max_quads * 4), None);

    let disc_program = cache.get("spectra/overlay/disc.glsl", vec![DISC_SCREEN_RATIO.sem("ratio")]).unwrap();
    let discs = Tess::new(Mode::Point, TessVertices::Reserve::<Disc>(max_discs), None);

    let text_program = cache.get("spectra/overlay/text.glsl", vec![
      TEXT_SAMPLER.sem("text_texture"),
      TEXT_POS.sem("pos"),
      TEXT_SIZE.sem("size"),
      TEXT_SCALE.sem("scale"),
      TEXT_COLOR.sem("color")
    ]).unwrap();

    let text_quad = Tess::attributeless(Mode::TriangleStrip, 4);

    Overlay {
      ratio: w as f32 / h as f32,
      tri_program: tri_program,
      tris: RefCell::new(tris),
      disc_program: disc_program,
      discs: RefCell::new(discs),
      text_program: text_program,
      text_quad: text_quad,
      unit_converter: UnitConverter::new(w, h)
    }
  }

  /// Dispatch render input primitives into GPU buffers.
  fn dispatch(&self, input: &RenderInput) -> (usize, usize) {
    let mut tris_ref = self.tris.borrow_mut();
    let mut tris = tris_ref.as_slice_mut().unwrap();
    let mut tri_i = 0;

    let mut discs_ref = self.discs.borrow_mut();
    let mut discs = discs_ref.as_slice_mut().unwrap();
    let mut disc_i = 0;

    for &Triangle(a, b, c) in input.triangles {
      let abc = [a, b, c];

      for &v in &abc {
        tris[tri_i] = v.to_clip_space(&self.unit_converter);
        tri_i += 1;
      }
    }

    for &Quad(a, b, c, d) in input.quads {
      let abcd = [a, b, c, c, b, d];

      for &v in &abcd {
        tris[tri_i] = v.to_clip_space(&self.unit_converter);
        tri_i += 1;
      }
    }

    for disc in input.discs {
      discs[disc_i] = disc.to_clip_space(&self.unit_converter);
      disc_i += 1;
    }

    (tri_i, disc_i)
  }

  pub fn render(&self, framebuffer: &Framebuffer2D<ColorMap, DepthMap>, input: &RenderInput) {
    let (tri_vert_nb, disc_vert_nb) = self.dispatch(input);

    let tris_ref = self.tris.borrow();
    let tris = TessRender::one_sub(&tris_ref, tri_vert_nb);

    let discs_ref = self.discs.borrow();
    let discs = TessRender::one_sub(&discs_ref, disc_vert_nb);

    let text_quad = TessRender::one_whole(&self.text_quad);

    let tri_program = self.tri_program.borrow();
    let disc_program = self.disc_program.borrow();
    let text_program = self.text_program.borrow();

    Pipeline::new(framebuffer, [0., 0., 0., 0.], &[], &[]).enter(|shd_gate| {
      shd_gate.new(&tri_program, &[], &[], &[]).enter(|rdr_gate| {
        rdr_gate.new(None, true, &[], &[], &[]).enter(|tess_gate| {
          tess_gate.render(tris, &[], &[], &[]);
        });
      });

      shd_gate.new(&disc_program, &[DISC_SCREEN_RATIO.alter(self.ratio)], &[], &[]).enter(|rdr_gate| {
        rdr_gate.new(None, true, &[], &[], &[]).enter(|tess_gate| {
          tess_gate.render(discs, &[], &[], &[]);
        });
      });

      if let Some((texts, text_scale)) = input.texts {
        shd_gate.new(&text_program, &[], &[], &[]).enter(|rdr_gate| {
          for text in texts {
            let blending = (Equation::Additive, Factor::One, Factor::SrcAlphaComplement);
            let (tex_w, tex_h) = text.text_texture.size();
            let uniforms = [
              TEXT_SAMPLER.alter(Unit::new(0)),
              TEXT_POS.alter(text.left_lower.to_clip_space(&self.unit_converter).pos),
              TEXT_SIZE.alter(self.unit_converter.from_win_dim(tex_w as f32, tex_h as f32)),
              TEXT_SCALE.alter(text_scale),
              TEXT_COLOR.alter(text.left_lower.color),
            ];

            rdr_gate.new(blending, true, &uniforms, &[&***text.text_texture], &[]).enter(|tess_gate| {
              tess_gate.render(text_quad.clone(), &[], &[], &[]);
            });
          }
        });
      }
    });
  }
}

#[derive(Clone)]
pub struct RenderInput<'a> {
  triangles: &'a [Triangle],
  quads: &'a [Quad],
  discs: &'a [Disc],
  texts: Option<(&'a [Text<'a>], f32)>
}

impl<'a> RenderInput<'a> {
  pub fn new() -> Self {
    RenderInput {
      triangles: &[],
      quads: &[],
      discs: &[],
      texts: None,
    }
  }

  pub fn triangles(self, triangles: &'a [Triangle]) -> Self {
    RenderInput {
      triangles: triangles,
      ..self
    }
  }

  pub fn quads(self, quads: &'a [Quad]) -> Self {
    RenderInput {
      quads: quads,
      ..self
    }
  }

  pub fn discs(self, discs: &'a [Disc]) -> Self {
    RenderInput {
      discs: discs,
      ..self
    }
  }

  pub fn texts(self, texts: &'a [Text<'a>], scale: f32) -> Self {
    RenderInput {
      texts: Some((texts, scale.max(0.))),
      ..self
    }
  }
}

/// A *unit converter* is used to position stuff in overlay in a universal and screen independent
/// way.
///
/// The idea is that you provide should handle *window space* coordinates only. This type will then
/// help compute normalized coordinates the renderer can understand.
///
/// For the record, *window space* coordinates are defined as below – given a viewport size of
/// *w × h*:
///
/// ^ y = h
/// |
/// |
/// |    x = w
/// O------>
///
/// The formula used to convert from *window space* to what we call *clip space* is:
///
/// > x' = 2x / w - 1
/// > y' = 2y / h - 1
#[derive(Copy, Clone, Debug, PartialEq)]
struct UnitConverter {
  rw: f32,
  rh: f32,
  twice_rw: f32,
  twice_rh: f32
}

impl UnitConverter {
  /// Build a unit converter by giving it the size of the viewport.
  pub fn new(w: u32, h: u32) -> Self {
    let rw = 1. / (w as f32);
    let rh = 1. / (h as f32);

    UnitConverter {
      rw: rw,
      rh: rh,
      twice_rw: 2. * rw,
      twice_rh: 2. * rh
    }
  }

  /// Convert from *window space* coordinates to clip space* ones.
  pub fn from_win_coord(&self, x: f32, y: f32) -> [f32; 2] {
    let x_ = x * self.twice_rw - 1.;
    let y_ = y * self.twice_rh - 1.;

    [x_.min(1.).max(-1.), y_.min(1.).max(-1.)]
  }

  /// Convert from *window space* dimensions to clip space* ones.
  pub fn from_win_dim(&self, w: f32, h: f32) -> [f32; 2] {
    let w_ = w * self.rw;
    let h_ = h * self.rh;

    [w_.min(1.).max(-1.), h_.min(1.).max(-1.)]
  }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;

enum PackageType {
    Bin, // Binary
    Lib, // Library
    Src, // Source
}

struct Version {
    major: u32,
    minor: u32,
    patch: u32,
    additional: Option<String>,
}

struct Package {
    name: String,
    hash: u32,
    version: Version,
    package_type: PackageType,
    dependencies: Vec<Package>,
}

struct Repository {
    url: String,
    packages: Vec<Package>,
}

impl PartialEq for Version {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

impl Eq for Version {}

impl PartialOrd for Version {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Version {
    /// This compares one `Version` with another. It only compares the
    /// three main parts of Version (`major`, `minor`, `patch`) and ignores
    /// `additional` as it is meant to let the package host to put additional
    /// messages such as `alpha`, `beta`.
    fn cmp(&self, other: &Self) -> Ordering {
        if self.major > other.major { Ordering::Greater } else
        if self.major < other.major { Ordering::Less }
        else {
            if self.minor > other.minor { Ordering::Greater } else
            if self.minor < other.minor { Ordering::Less }
            else {
                if self.patch > other.patch { Ordering::Greater } else
                if self.patch < other.patch { Ordering::Less }
                else { Ordering::Equal }
            }
        }
    }
}
<commit_msg>Finishing touches on Version<commit_after>use std::cmp::Ordering;

enum PackageType {
    Bin, // Binary
    Lib, // Library
    Src, // Source
}

/// A struct made for storing the version of the packages.
///
/// The format follows [semver 2.0](http://semver.org/), meaning that:
///
/// - versions with different `major` indicates that they are incompatible.
/// - versions with different `minor` but same `major` are largely compatible.
/// - versions with different `patch` but same `major` and `minor` are
///   compatible.
///
/// The `additional` field is an optional field for the package host to put
/// text such as `alpha` or `stable`, it's not involved in the comparisons.
pub struct Version {
    major: u32,
    minor: u32,
    patch: u32,
    additional: Option<String>,
}

struct Package {
    name: String,
    hash: u32,
    version: Version,
    package_type: PackageType,
    dependencies: Vec<Package>,
}

struct Repository {
    url: String,
    packages: Vec<Package>,
}

impl PartialEq for Version {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

impl Eq for Version {}

impl PartialOrd for Version {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Version {
    /// This compares one `Version` with another. It only compares the
    /// three main parts of Version (`major`, `minor`, `patch`) and ignores
    /// `additional` as it is meant to let the package host to put additional
    /// messages such as `alpha`, `beta`.
    ///
    /// This functions compares the two `Version`s *absolutely*, meaning that
    /// it doesn't care about whether the two versions are breaking-changes or
    /// not - it just compares.
    fn cmp(&self, other: &Self) -> Ordering {
        if self.major > other.major { Ordering::Greater } else
        if self.major < other.major { Ordering::Less }
        else {
            if self.minor > other.minor { Ordering::Greater } else
            if self.minor < other.minor { Ordering::Less }
            else {
                if self.patch > other.patch { Ordering::Greater } else
                if self.patch < other.patch { Ordering::Less }
                else { Ordering::Equal }
            }
        }
    }
}

impl Version {
    /// Returns the major version X (X.y.z).
    pub fn major(&self) -> u32 {
        self.major
    }

    /// Returns the minor version Y (x.Y.z).
    pub fn minor(&self) -> u32 {
        self.minor
    }

    /// Returns the patch version Z (x.y.Z).
    pub fn patch(&self) -> u32 {
        self.patch
    }

    /// Returns the additional message added by package host or its developers.
    pub fn additional(&self) -> &Option<String> {
        &self.additional
    }

    /// A helper function for checking whether the two versions contains
    /// breaking changes.
    pub fn is_back_compatible(&self, other: &Self) -> bool {
        self.major == other.major
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::fs;
use std::io::{self, Read};
use std::path;

use Predicate;

fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
    let mut buffer = Vec::new();
    fs::File::open(path)?.read_to_end(&mut buffer)?;
    Ok(buffer)
}

/// Predicate that compares file matches
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BinaryFilePredicate {
    path: path::PathBuf,
    content: Vec<u8>,
}

impl BinaryFilePredicate {
    fn eval(&self, path: &path::Path) -> io::Result<bool> {
        let content = read_file(path)?;
        Ok(self.content == content)
    }

    /// Creates a new `Predicate` that ensures complete equality
    ///
    /// # Examples
    ///
    /// ```
    /// use std::path::Path;
    /// use predicates::prelude::*;
    ///
    /// let predicate_file = predicate::path::eq_file(Path::new("Cargo.toml")).utf8().unwrap();
    /// assert_eq!(true, predicate_file.eval(Path::new("Cargo.toml")));
    /// assert_eq!(false, predicate_file.eval(Path::new("Cargo.lock")));
    /// assert_eq!(false, predicate_file.eval(Path::new("src")));
    /// ```
    pub fn utf8(self) -> Option<StrFilePredicate> {
        let path = self.path;
        let content = String::from_utf8(self.content).ok()?;
        Some(StrFilePredicate { path, content })
    }
}

impl Predicate<path::Path> for BinaryFilePredicate {
    fn eval(&self, path: &path::Path) -> bool {
        self.eval(path).unwrap_or(false)
    }
}

impl fmt::Display for BinaryFilePredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "var is {}", self.path.display())
    }
}

/// Creates a new `Predicate` that ensures complete equality
///
/// # Examples
///
/// ```
/// use std::path::Path;
/// use predicates::prelude::*;
///
/// let predicate_file = predicate::path::eq_file(Path::new("Cargo.toml"));
/// assert_eq!(true, predicate_file.eval(Path::new("Cargo.toml")));
/// assert_eq!(false, predicate_file.eval(Path::new("src")));
/// assert_eq!(false, predicate_file.eval(Path::new("Cargo.lock")));
/// ```
pub fn eq_file(path: &path::Path) -> BinaryFilePredicate {
    let content = read_file(path).unwrap();
    BinaryFilePredicate {
        path: path.to_path_buf(),
        content,
    }
}

/// Predicate that compares string content of files
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StrFilePredicate {
    path: path::PathBuf,
    content: String,
}

impl StrFilePredicate {
    fn eval(&self, path: &path::Path) -> Option<bool> {
        let content = read_file(path).ok()?;
        let content = String::from_utf8(content).ok()?;
        Some(self.content == content)
    }
}

impl fmt::Display for StrFilePredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "var is {}", self.path.display())
    }
}

impl Predicate<path::Path> for StrFilePredicate {
    fn eval(&self, path: &path::Path) -> bool {
        self.eval(path).unwrap_or(false)
    }
}
<commit_msg>feat(path): support file-based str predicates<commit_after>// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::fs;
use std::io::{self, Read};
use std::path;

use Predicate;

fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
    let mut buffer = Vec::new();
    fs::File::open(path)?.read_to_end(&mut buffer)?;
    Ok(buffer)
}

/// Predicate that compares file matches
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BinaryFilePredicate {
    path: path::PathBuf,
    content: Vec<u8>,
}

impl BinaryFilePredicate {
    fn eval(&self, path: &path::Path) -> io::Result<bool> {
        let content = read_file(path)?;
        Ok(self.content == content)
    }

    /// Creates a new `Predicate` that ensures complete equality
    ///
    /// # Examples
    ///
    /// ```
    /// use std::path::Path;
    /// use predicates::prelude::*;
    ///
    /// let predicate_file = predicate::path::eq_file(Path::new("Cargo.toml")).utf8().unwrap();
    /// assert_eq!(true, predicate_file.eval(Path::new("Cargo.toml")));
    /// assert_eq!(false, predicate_file.eval(Path::new("Cargo.lock")));
    /// assert_eq!(false, predicate_file.eval(Path::new("src")));
    ///
    /// assert_eq!(false, predicate_file.eval("Not a real Cargo.toml file content"));
    /// ```
    pub fn utf8(self) -> Option<StrFilePredicate> {
        let path = self.path;
        let content = String::from_utf8(self.content).ok()?;
        Some(StrFilePredicate { path, content })
    }
}

impl Predicate<path::Path> for BinaryFilePredicate {
    fn eval(&self, path: &path::Path) -> bool {
        self.eval(path).unwrap_or(false)
    }
}

impl Predicate<[u8]> for BinaryFilePredicate {
    fn eval(&self, actual: &[u8]) -> bool {
        self.content == actual
    }
}

impl fmt::Display for BinaryFilePredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "var is {}", self.path.display())
    }
}

/// Creates a new `Predicate` that ensures complete equality
///
/// # Examples
///
/// ```
/// use std::path::Path;
/// use predicates::prelude::*;
///
/// let predicate_file = predicate::path::eq_file(Path::new("Cargo.toml"));
/// assert_eq!(true, predicate_file.eval(Path::new("Cargo.toml")));
/// assert_eq!(false, predicate_file.eval(Path::new("src")));
/// assert_eq!(false, predicate_file.eval(Path::new("Cargo.lock")));
/// ```
pub fn eq_file(path: &path::Path) -> BinaryFilePredicate {
    let content = read_file(path).unwrap();
    BinaryFilePredicate {
        path: path.to_path_buf(),
        content,
    }
}

/// Predicate that compares string content of files
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StrFilePredicate {
    path: path::PathBuf,
    content: String,
}

impl StrFilePredicate {
    fn eval(&self, path: &path::Path) -> Option<bool> {
        let content = read_file(path).ok()?;
        let content = String::from_utf8(content).ok()?;
        Some(self.content == content)
    }
}

impl Predicate<path::Path> for StrFilePredicate {
    fn eval(&self, path: &path::Path) -> bool {
        self.eval(path).unwrap_or(false)
    }
}

impl Predicate<str> for StrFilePredicate {
    fn eval(&self, actual: &str) -> bool {
        self.content == actual
    }
}

impl fmt::Display for StrFilePredicate {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "var is {}", self.path.display())
    }
}
<|endoftext|>


<commit_before>#![macro_escape]

pub struct BestFailure<'a, E> {
    pub failure: Option<Progress<'a, E>>
}

impl<'a, E> BestFailure<'a, E> {
    pub fn new() -> BestFailure<'a, E> {
        BestFailure {
            failure: None,
        }
    }

    pub fn with(failure: Progress<'a, E>) -> BestFailure<'a, E> {
        BestFailure {
            failure: Some(failure),
        }
    }

    pub fn push(&mut self, failure: Progress<'a, E>) {
        if let Some(ref old) = self.failure {
            if failure.point.offset <= old.point.offset {
                return;
            }
        }

        self.failure = Some(failure)
    }

    pub fn pop(self) -> Progress<'a, E> {
        self.failure.expect("No errors found")
    }
}

#[deriving(Show,Clone,PartialEq,Copy)]
pub struct Point<'a> {
    pub offset: uint,
    pub s: &'a str,
}

impl<'a> Point<'a> {
    pub fn to(&self, other: Point<'a>) -> &'a str {
        let len = other.offset - self.offset;
        self.s.slice_to(len)
    }

    pub fn slice_at(&self, position: uint) -> Progress<'a, &'a str> {
        Progress {
            data: self.s.slice_to(position),
            point: Point { offset: self.offset + position,
                           s: self.s.slice_from(position) }
        }
    }

    pub fn consume_to<E>(&self, l: Option<uint>) -> Result<'a, &'a str, E> {
        match l {
            None => Result::Failure(Progress{point: self.clone(), data: None}),
            Some(position) => Result::Success(self.slice_at(position)),
        }
    }
}

pub struct Progress<'a, T> {
    pub point: Point<'a>,
    pub data: T,
}

impl<'a, T> Progress<'a, T> {
    pub fn to_tuple(self) -> (T, Point<'a>) {
        (self.data, self.point)
    }

    pub fn map<F, B>(self, f: F) -> Progress<'a, B>
        where F: Fn(T) -> B
    {
        Progress { data: f(self.data), point: self.point }
    }
}

pub enum Result<'a, T, E> {
    Success(Progress<'a, T>),
    Partial{success: Progress<'a, T>, failure: Progress<'a, Option<E>>},
    Failure(Progress<'a, Option<E>>),
}

impl<'a, T, E> Result<'a, T, E> {
    pub fn success(data: T, point: Point<'a>) -> Result<'a, T, E> {
        Result::Success(Progress { data: data, point: point })
    }

    pub fn map<F, B>(self, f: F) -> Result<'a, B, E>
        where F: Fn(T) -> B
    {
        match self {
            Result::Success(prog) =>
                Result::Success(prog.map(f)),
            Result::Partial{success: s, failure: ff} => {
                Result::Partial{ success: s.map(f), failure: ff}
            },
            Result::Failure(pf) =>
                Result::Failure(pf),
        }
    }
}

macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                progress.to_tuple(),
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) =>
                return ::document::peresil::Result::Failure(pf),
        }
    })
);

macro_rules! try_partial_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                (progress.data, ::document::peresil::BestFailure::new(), progress.point),
            ::document::peresil::Result::Partial{ success: s, failure: pf } =>
                (s.data, ::document::peresil::BestFailure::with(pf), s.point),
            ::document::peresil::Result::Failure(pf) =>
                return ::document::peresil::Result::Failure(pf),
        }
    })
);

macro_rules! try_resume_after_partial_failure(
    ($partial:expr, $e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                progress.to_tuple(),
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) => {
                let mut partial = $partial;
                partial.push(pf);
                return ::document::peresil::Result::Failure(partial.pop())
            },
        }
    });
);

// Pattern: zero-or-one
macro_rules! parse_optional(
    ($parser:expr, $start:expr) => ({
        match $parser {
            ::document::peresil::Result::Success(progress) |
            ::document::peresil::Result::Partial{ success: progress, .. } =>
                (Some(progress.data), progress.point),
            ::document::peresil::Result::Failure(_) =>
                (None, $start),
        }
    })
);

// Pattern: alternate
macro_rules! parse_alternate_rec(
    ($start:expr, $errors:expr, {}) => ({
        ::document::peresil::Result::Failure($errors.pop())
    });
    ($start:expr, $errors:expr, {
        $parser:expr,
        $($parser_rest:expr,)*
    }) => ({
        let result = $parser($start);
        match result {
            ::document::peresil::Result::Success(..) =>
                result,
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) => {
                $errors.push(pf);
                parse_alternate_rec!($start, $errors, {
                    $($parser_rest,)*
                })
            },
        }
    });
);

macro_rules! parse_alternate(
    ($start:expr, {
        $($parser_rest:expr,)*
    }) => ({
        let mut errors = ::document::peresil::BestFailure::new();
        parse_alternate_rec!($start, errors, {
            $($parser_rest,)*
        })
    });
);

// Pattern: zero-or-more
macro_rules! parse_zero_or_more(
    ($start:expr, $parser:expr) => {{
        let mut err;

        let mut start = $start;
        loop {
            let (_, next_start) = match $parser(start) {
                ::document::peresil::Result::Success(progress) =>
                    progress.to_tuple(),
                ::document::peresil::Result::Partial{ failure: pf, ..} |
                ::document::peresil::Result::Failure(pf) => {
                    err = Some(pf);
                    break
                }
            };

            start = next_start;
        }

        ::document::peresil::Result::Partial {
            success: ::document::peresil::Progress { data: (), point: start },
            failure: err.unwrap()
        }
    }};
);
<commit_msg>Export the macros for reuse in other crates<commit_after>#![macro_escape]

pub struct BestFailure<'a, E> {
    pub failure: Option<Progress<'a, E>>
}

impl<'a, E> BestFailure<'a, E> {
    pub fn new() -> BestFailure<'a, E> {
        BestFailure {
            failure: None,
        }
    }

    pub fn with(failure: Progress<'a, E>) -> BestFailure<'a, E> {
        BestFailure {
            failure: Some(failure),
        }
    }

    pub fn push(&mut self, failure: Progress<'a, E>) {
        if let Some(ref old) = self.failure {
            if failure.point.offset <= old.point.offset {
                return;
            }
        }

        self.failure = Some(failure)
    }

    pub fn pop(self) -> Progress<'a, E> {
        self.failure.expect("No errors found")
    }
}

#[deriving(Show,Clone,PartialEq,Copy)]
pub struct Point<'a> {
    pub offset: uint,
    pub s: &'a str,
}

impl<'a> Point<'a> {
    pub fn to(&self, other: Point<'a>) -> &'a str {
        let len = other.offset - self.offset;
        self.s.slice_to(len)
    }

    pub fn slice_at(&self, position: uint) -> Progress<'a, &'a str> {
        Progress {
            data: self.s.slice_to(position),
            point: Point { offset: self.offset + position,
                           s: self.s.slice_from(position) }
        }
    }

    pub fn consume_to<E>(&self, l: Option<uint>) -> Result<'a, &'a str, E> {
        match l {
            None => Result::Failure(Progress{point: self.clone(), data: None}),
            Some(position) => Result::Success(self.slice_at(position)),
        }
    }
}

pub struct Progress<'a, T> {
    pub point: Point<'a>,
    pub data: T,
}

impl<'a, T> Progress<'a, T> {
    pub fn to_tuple(self) -> (T, Point<'a>) {
        (self.data, self.point)
    }

    pub fn map<F, B>(self, f: F) -> Progress<'a, B>
        where F: Fn(T) -> B
    {
        Progress { data: f(self.data), point: self.point }
    }
}

pub enum Result<'a, T, E> {
    Success(Progress<'a, T>),
    Partial{success: Progress<'a, T>, failure: Progress<'a, Option<E>>},
    Failure(Progress<'a, Option<E>>),
}

impl<'a, T, E> Result<'a, T, E> {
    pub fn success(data: T, point: Point<'a>) -> Result<'a, T, E> {
        Result::Success(Progress { data: data, point: point })
    }

    pub fn map<F, B>(self, f: F) -> Result<'a, B, E>
        where F: Fn(T) -> B
    {
        match self {
            Result::Success(prog) =>
                Result::Success(prog.map(f)),
            Result::Partial{success: s, failure: ff} => {
                Result::Partial{ success: s.map(f), failure: ff}
            },
            Result::Failure(pf) =>
                Result::Failure(pf),
        }
    }
}

#[macro_export]
macro_rules! try_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                progress.to_tuple(),
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) =>
                return ::document::peresil::Result::Failure(pf),
        }
    })
);

#[macro_export]
macro_rules! try_partial_parse(
    ($e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                (progress.data, ::document::peresil::BestFailure::new(), progress.point),
            ::document::peresil::Result::Partial{ success: s, failure: pf } =>
                (s.data, ::document::peresil::BestFailure::with(pf), s.point),
            ::document::peresil::Result::Failure(pf) =>
                return ::document::peresil::Result::Failure(pf),
        }
    })
);

#[macro_export]
macro_rules! try_resume_after_partial_failure(
    ($partial:expr, $e:expr) => ({
        match $e {
            ::document::peresil::Result::Success(progress) =>
                progress.to_tuple(),
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) => {
                let mut partial = $partial;
                partial.push(pf);
                return ::document::peresil::Result::Failure(partial.pop())
            },
        }
    });
);

// Pattern: zero-or-one
#[macro_export]
macro_rules! parse_optional(
    ($parser:expr, $start:expr) => ({
        match $parser {
            ::document::peresil::Result::Success(progress) |
            ::document::peresil::Result::Partial{ success: progress, .. } =>
                (Some(progress.data), progress.point),
            ::document::peresil::Result::Failure(_) =>
                (None, $start),
        }
    })
);

// Pattern: alternate
#[macro_export]
macro_rules! parse_alternate_rec(
    ($start:expr, $errors:expr, {}) => ({
        ::document::peresil::Result::Failure($errors.pop())
    });
    ($start:expr, $errors:expr, {
        $parser:expr,
        $($parser_rest:expr,)*
    }) => ({
        let result = $parser($start);
        match result {
            ::document::peresil::Result::Success(..) =>
                result,
            ::document::peresil::Result::Partial{ failure: pf, .. } |
            ::document::peresil::Result::Failure(pf) => {
                $errors.push(pf);
                parse_alternate_rec!($start, $errors, {
                    $($parser_rest,)*
                })
            },
        }
    });
);

#[macro_export]
macro_rules! parse_alternate(
    ($start:expr, {
        $($parser_rest:expr,)*
    }) => ({
        let mut errors = ::document::peresil::BestFailure::new();
        parse_alternate_rec!($start, errors, {
            $($parser_rest,)*
        })
    });
);

// Pattern: zero-or-more
#[macro_export]
macro_rules! parse_zero_or_more(
    ($start:expr, $parser:expr) => {{
        let mut err;

        let mut start = $start;
        loop {
            let (_, next_start) = match $parser(start) {
                ::document::peresil::Result::Success(progress) =>
                    progress.to_tuple(),
                ::document::peresil::Result::Partial{ failure: pf, ..} |
                ::document::peresil::Result::Failure(pf) => {
                    err = Some(pf);
                    break
                }
            };

            start = next_start;
        }

        ::document::peresil::Result::Partial {
            success: ::document::peresil::Progress { data: (), point: start },
            failure: err.unwrap()
        }
    }};
);
<|endoftext|>


<commit_before>
//! Trying to module physics using state research.

use UpdateDelta = state::UpdateDelta;

/// The difference in time from one frame to the next.
pub struct DeltaTime(f64);

pub type Position = [f64, ..3];
pub type Velocity = [f64, ..3];
pub type Acceleration = [f64, ..3];
pub type Force = [f64, ..3];
pub type Mass = f64;
pub type InvMass = f64;

/// Object in motion under no force.
pub struct NoForce {
    /// The position of object.
    pub pos: Position,
    /// The velocity of object.
    pub vel: Velocity,
}

impl UpdateDelta<DeltaTime> for NoForce {
    #[inline(always)]
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            self.pos[i] += self.vel[i] * dt;
        }
    }
}

/// Moves point with acceleration.
pub struct WithAcceleration {
    /// The position of object.
    pub pos: Position,
    /// The velocity of object.
    pub vel: Velocity,
    /// The acceleration on object.
    pub acc: Acceleration,
}

impl UpdateDelta<DeltaTime> for WithAcceleration {
    #[inline(always)]
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            let vel_next = self.vel[i] + self.acc[i] * dt;
            self.pos[i] += 0.5 * dt * (self.vel[i] + vel_next);
        }
    }
}

/// Moves with force.
pub struct WithForce {
    /// The position.
    pub pos: Position,
    /// The velocity.
    pub vel: Velocity,
    /// The force.
    pub force: Force,
    /// The inverse mass.
    pub inv_mass: InvMass,
}

impl UpdateDelta<DeltaTime> for WithForce {
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            let acc = self.force[i] * self.inv_mass;
            let vel_next = self.vel[i] + acc * dt;
            self.pos[i] += 0.5 * dt * (self.vel[i] + vel_next);
        }
    }
}

<commit_msg>Added PositionProperty<commit_after>
//! Trying to module physics using state research.

use UpdateDelta = state::UpdateDelta;

/// The difference in time from one frame to the next.
pub struct DeltaTime(f64);

pub type Position = [f64, ..3];
pub type Velocity = [f64, ..3];
pub type Acceleration = [f64, ..3];
pub type Force = [f64, ..3];
pub type Mass = f64;
pub type InvMass = f64;

/// Gets the position.
pub trait PositionProperty {
    /// Get a readonly position.
    fn pos<'a>(&'a self) -> &'a Position;
    /// Get a mutable position.
    fn pos_mut<'a>(&'a mut self) -> &'a mut Position;
}

/// Object in motion under no force.
pub struct NoForce {
    /// The position of object.
    pub pos: Position,
    /// The velocity of object.
    pub vel: Velocity,
}

impl UpdateDelta<DeltaTime> for NoForce {
    #[inline(always)]
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            self.pos[i] += self.vel[i] * dt;
        }
    }
}

impl PositionProperty for NoForce {
    #[inline(always)]
    fn pos<'a>(&'a self) -> &'a Position {
        &self.pos
    }

    #[inline(always)]
    fn pos_mut<'a>(&'a mut self) -> &'a mut Position {
        &mut self.pos
    }
}

/// Moves point with acceleration.
pub struct WithAcceleration {
    /// The position of object.
    pub pos: Position,
    /// The velocity of object.
    pub vel: Velocity,
    /// The acceleration on object.
    pub acc: Acceleration,
}

impl UpdateDelta<DeltaTime> for WithAcceleration {
    #[inline(always)]
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            let vel_next = self.vel[i] + self.acc[i] * dt;
            self.pos[i] += 0.5 * dt * (self.vel[i] + vel_next);
        }
    }
}

impl PositionProperty for WithAcceleration {
    fn pos<'a>(&'a self) -> &'a Position {
        &self.pos
    }

    fn pos_mut<'a>(&'a mut self) -> &'a mut Position {
        &mut self.pos
    }
}

/// Moves with force.
pub struct WithForce {
    /// The position.
    pub pos: Position,
    /// The velocity.
    pub vel: Velocity,
    /// The force.
    pub force: Force,
    /// The inverse mass.
    pub inv_mass: InvMass,
}

impl UpdateDelta<DeltaTime> for WithForce {
    fn update(&mut self, &DeltaTime(dt): &DeltaTime) {
        for i in range(0u, 3) {
            let acc = self.force[i] * self.inv_mass;
            let vel_next = self.vel[i] + acc * dt;
            self.pos[i] += 0.5 * dt * (self.vel[i] + vel_next);
        }
    }
}

impl PositionProperty for WithForce {
    fn pos<'a>(&'a self) -> &'a Position {
        &self.pos
    }

    fn pos_mut<'a>(&'a mut self) -> &'a mut Position {
        &mut self.pos
    }
}

<|endoftext|>


<commit_before>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: GPL-2.0
//

use checked_command;
use cmdline_words_parser::StrExt;

pub fn run(cmd: &str) -> Result<checked_command::Output, checked_command::Error> {
    let mut cmd = cmd.to_string();
    let mut cmd = cmd.parse_cmdline_words();

    let mut p = checked_command::CheckedCommand::new(cmd.next().unwrap());
    for arg in cmd {
        p.arg(arg);
    }

    Ok(p.output()?)
}

#[test]
fn stdout() {
    // stdout
    let output = run(r#"sh -c 'echo "1 2 3 4"'"#).unwrap();
    assert_eq!(String::from_utf8_lossy(&output.stdout), "1 2 3 4\n");
}

#[test]
fn stderr() {
    // stderr
    let output = run(r#"sh -c 'echo "1 2 3 4" >&2'"#).unwrap();
    assert_eq!(String::from_utf8_lossy(&output.stderr), "1 2 3 4\n");
}

#[test]
fn failing_command() {
    // failing command with exit status 1
    let r = run(r#"sh -c 'echo "error" >&2; exit 1'"#);
    match r {
        Ok(_) => panic!("call should have failed"),
        Err(checked_command::Error::Io(io_err)) => panic!("unexpected I/O Error: {:?}", io_err),
        Err(checked_command::Error::Failure(ex, output)) => {
            assert_eq!(ex.code().unwrap(), 1);
            assert_eq!(String::from_utf8_lossy(&output.unwrap().stderr), "error\n");
        }
    }
}
<commit_msg>process: Add documentation<commit_after>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: GPL-2.0
//

//! Allow running external commands.

use checked_command;
use cmdline_words_parser::StrExt;

/// Run the given command
///
/// # Arguments
///
/// `cmd` - A string slice containing the command to be run.
///
/// # Example
/// ```
/// use updatehub::process;
///
/// // stdout
/// let output = process::run(r#"sh -c 'echo "1 2 3 4"'"#).unwrap();
/// assert_eq!(String::from_utf8_lossy(&output.stdout), "1 2 3 4\n");
///
/// // stderr
/// let output = process::run(r#"sh -c 'echo "1 2 3 4" >&2'"#).unwrap();
/// assert_eq!(String::from_utf8_lossy(&output.stderr), "1 2 3 4\n");
/// ```
pub fn run(cmd: &str) -> Result<checked_command::Output, checked_command::Error> {
    let mut cmd = cmd.to_string();
    let mut cmd = cmd.parse_cmdline_words();

    let mut p = checked_command::CheckedCommand::new(cmd.next().unwrap());
    for arg in cmd {
        p.arg(arg);
    }

    Ok(p.output()?)
}

#[test]
fn failing_command() {
    // failing command with exit status 1
    let r = run(r#"sh -c 'echo "error" >&2; exit 1'"#);
    match r {
        Ok(_) => panic!("call should have failed"),
        Err(checked_command::Error::Io(io_err)) => panic!("unexpected I/O Error: {:?}", io_err),
        Err(checked_command::Error::Failure(ex, output)) => {
            assert_eq!(ex.code().unwrap(), 1);
            assert_eq!(String::from_utf8_lossy(&output.unwrap().stderr), "error\n");
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    let decoder = Decoder;
    let mut harness = toml_test_harness::DecoderHarness::new(decoder);
    harness
        .ignore([
            "valid/array/array.toml",
            "valid/comment/everywhere.toml",
            "valid/datetime/datetime.toml",
            "valid/datetime/local-date.toml",
            "valid/datetime/local-time.toml",
            "valid/datetime/local.toml",
            "valid/datetime/milliseconds.toml",
            "valid/datetime/timezone.toml",
            "valid/example.toml",
            "valid/float/underscore.toml",
            "valid/float/zero.toml",
            "valid/inline-table/key-dotted.toml",
            "valid/key/dotted.toml",
            "valid/key/numeric-dotted.toml",
            "valid/spec-example-1-compact.toml",
            "valid/spec-example-1.toml",
            "valid/string/multiline-quotes.toml",
        ])
        .unwrap();
    harness.test();
}

struct Decoder;

impl toml_test_harness::Decoder for Decoder {
    fn name(&self) -> &str {
        "toml_edit"
    }

    fn decode(&self, data: &[u8]) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
        let data = std::str::from_utf8(data).map_err(toml_test_harness::Error::new)?;
        let document = data
            .parse::<toml_edit::Document>()
            .map_err(toml_test_harness::Error::new)?;
        document_to_encoded(&document)
    }
}

fn document_to_encoded(
    value: &toml_edit::Document,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    item_to_encoded(&value.root)
}

fn item_to_encoded(
    value: &toml_edit::Item,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    match value {
        toml_edit::Item::None => unreachable!("No nones"),
        toml_edit::Item::Value(v) => value_to_encoded(v),
        toml_edit::Item::Table(v) => table_to_encoded(v),
        toml_edit::Item::ArrayOfTables(v) => {
            let v: Result<_, toml_test_harness::Error> = v.iter().map(table_to_encoded).collect();
            Ok(toml_test_harness::Encoded::Array(v?))
        }
    }
}

fn value_to_encoded(
    value: &toml_edit::Value,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    match value {
        toml_edit::Value::Integer(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::String(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(v.value()),
        )),
        toml_edit::Value::Float(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::DateTime(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(v.value().to_string()),
        )),
        toml_edit::Value::Boolean(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::Array(v) => {
            let v: Result<_, toml_test_harness::Error> = v.iter().map(value_to_encoded).collect();
            Ok(toml_test_harness::Encoded::Array(v?))
        }
        toml_edit::Value::InlineTable(v) => inline_table_to_encoded(v),
    }
}

fn table_to_encoded(
    value: &toml_edit::Table,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    let table: Result<_, toml_test_harness::Error> = value
        .iter()
        .map(|(k, v)| {
            let k = k.to_owned();
            let v = item_to_encoded(v)?;
            Ok((k, v))
        })
        .collect();
    Ok(toml_test_harness::Encoded::Table(table?))
}

fn inline_table_to_encoded(
    value: &toml_edit::InlineTable,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    let table: Result<_, toml_test_harness::Error> = value
        .iter()
        .map(|(k, v)| {
            let k = k.to_owned();
            let v = value_to_encoded(v)?;
            Ok((k, v))
        })
        .collect();
    Ok(toml_test_harness::Encoded::Table(table?))
}
<commit_msg>test: Enable underscore test<commit_after>fn main() {
    let decoder = Decoder;
    let mut harness = toml_test_harness::DecoderHarness::new(decoder);
    harness
        .ignore([
            "valid/array/array.toml",
            "valid/comment/everywhere.toml",
            "valid/datetime/datetime.toml",
            "valid/datetime/local-date.toml",
            "valid/datetime/local-time.toml",
            "valid/datetime/local.toml",
            "valid/datetime/milliseconds.toml",
            "valid/datetime/timezone.toml",
            "valid/example.toml",
            "valid/float/zero.toml",
            "valid/inline-table/key-dotted.toml",
            "valid/key/dotted.toml",
            "valid/key/numeric-dotted.toml",
            "valid/spec-example-1-compact.toml",
            "valid/spec-example-1.toml",
            "valid/string/multiline-quotes.toml",
        ])
        .unwrap();
    harness.test();
}

struct Decoder;

impl toml_test_harness::Decoder for Decoder {
    fn name(&self) -> &str {
        "toml_edit"
    }

    fn decode(&self, data: &[u8]) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
        let data = std::str::from_utf8(data).map_err(toml_test_harness::Error::new)?;
        let document = data
            .parse::<toml_edit::Document>()
            .map_err(toml_test_harness::Error::new)?;
        document_to_encoded(&document)
    }
}

fn document_to_encoded(
    value: &toml_edit::Document,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    item_to_encoded(&value.root)
}

fn item_to_encoded(
    value: &toml_edit::Item,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    match value {
        toml_edit::Item::None => unreachable!("No nones"),
        toml_edit::Item::Value(v) => value_to_encoded(v),
        toml_edit::Item::Table(v) => table_to_encoded(v),
        toml_edit::Item::ArrayOfTables(v) => {
            let v: Result<_, toml_test_harness::Error> = v.iter().map(table_to_encoded).collect();
            Ok(toml_test_harness::Encoded::Array(v?))
        }
    }
}

fn value_to_encoded(
    value: &toml_edit::Value,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    match value {
        toml_edit::Value::Integer(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::String(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(v.value()),
        )),
        toml_edit::Value::Float(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::DateTime(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(v.value().to_string()),
        )),
        toml_edit::Value::Boolean(v) => Ok(toml_test_harness::Encoded::Value(
            toml_test_harness::EncodedValue::from(*v.value()),
        )),
        toml_edit::Value::Array(v) => {
            let v: Result<_, toml_test_harness::Error> = v.iter().map(value_to_encoded).collect();
            Ok(toml_test_harness::Encoded::Array(v?))
        }
        toml_edit::Value::InlineTable(v) => inline_table_to_encoded(v),
    }
}

fn table_to_encoded(
    value: &toml_edit::Table,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    let table: Result<_, toml_test_harness::Error> = value
        .iter()
        .map(|(k, v)| {
            let k = k.to_owned();
            let v = item_to_encoded(v)?;
            Ok((k, v))
        })
        .collect();
    Ok(toml_test_harness::Encoded::Table(table?))
}

fn inline_table_to_encoded(
    value: &toml_edit::InlineTable,
) -> Result<toml_test_harness::Encoded, toml_test_harness::Error> {
    let table: Result<_, toml_test_harness::Error> = value
        .iter()
        .map(|(k, v)| {
            let k = k.to_owned();
            let v = value_to_encoded(v)?;
            Ok((k, v))
        })
        .collect();
    Ok(toml_test_harness::Encoded::Table(table?))
}
<|endoftext|>