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

pub struct PeekableReader<R> {
    inner: R,
    peeked_result: Option<IoResult<u8>>,
}

impl<R: Reader> PeekableReader<R> {
    /// Initializes a new `PeekableReader` which wraps the given underlying
    /// reader.
    pub fn new(reader: R) -> PeekableReader<R> {
        PeekableReader {
            inner: reader,
            peeked_result: None,
        }
    }

    pub fn peek(&mut self) -> IoResult<u8> {
        // Return either the currently cached peeked byte or obtain a new one
        // from the underlying reader.
        match self.peeked_result {
            Some(ref old_res) => old_res.clone(),
            None => {
                // First get the result of the read from the underlying reader
                self.peeked_result = Some(self.inner.read_byte());

                // Now just return that
                self.peeked_result.clone().unwrap()
            }
        }
    }
}

impl<R: Reader> Reader for PeekableReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        if buf.len() == 0 {
            return Ok(0);
        }

        // First, put the byte that was read off the underlying reader in a
        // (possible) previous peek operation (if such a byte is indeed cached)
        let offset = match self.peeked_result.clone() {
            Some(Err(e)) => {
                self.peeked_result = None;
                return Err(e);
            },
            Some(Ok(b)) => {
                buf[0] = b;
                self.peeked_result = None;
                1
            },
            None => 0,
        };

        if offset == 1 && buf.len() == 1 {
            // We've filled the buffer by using the previously peeked byte
            Ok(1)
        } else {
            // We are still missing more bytes, so we read them from the
            // underlying reader and place them directly in the correct place
            // in the buffer.
            let (_, leftover) = buf.split_at_mut(offset);
            Ok(try!(self.inner.read(leftover)) + offset)
        }
    }
}

mod tests {
    use super::PeekableReader;
    use std::io::{MemReader, IoError, IoErrorKind, IoResult};

    /// A mock implementation of the `Reader` trait that returns a given
    /// IoError after a certain number of bytes has been read. The error is
    /// returned only once, with subsequent read calls completing successfully
    /// again.
    /// When the Reader successfully reads a byte, it is always `0u8`.
    struct MockReaderWithError {
        error: IoError,
        after: uint,
        bytes_read: uint,
        errored: bool,
    }

    impl MockReaderWithError {
        fn new(error: IoError, after: uint) -> MockReaderWithError {
            MockReaderWithError {
                error: error,
                after: after,
                bytes_read: 0,
                errored: false,
            }
        }
    }

    impl Reader for MockReaderWithError {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            self.bytes_read += buf.len();
            if self.bytes_read <= self.after || self.errored {
                for b in buf.iter_mut() {
                    *b = 0;
                }

                Ok(buf.len())
            } else {
                self.errored = true;
                Err(self.error.clone())
            }
        }
    }

    /// Helper function which checks whether the given result indicated EOF.
    fn is_eof<T>(res: IoResult<T>) -> bool {
        match res {
            Err(IoError {
                kind: IoErrorKind::EndOfFile,
                ..
            }) => true,
            _ => false,
        }
    }

    /// Tests that it is possible to invoke the `peek` method multiple times
    /// with the same effect, when there are no intermediate reads.
    #[test]
    fn multiple_peeks_idempotent() {
        let b = 1;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b, b + 1)));

        // The first peek is correct?
        assert_eq!(b, reader.peek().unwrap());
        // The second peek (with no reads in between) still returns the same
        // byte?
        assert_eq!(b, reader.peek().unwrap());
    }

    #[test]
    fn single_byte_reader_peek() {
        let b = 5u8;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b)));

        // When we peek, we get the correct byte back?
        assert_eq!(b, reader.peek().unwrap());
    }

    #[test]
    fn empty_underlying_reader() {
        let mut reader = PeekableReader::new(MemReader::new(vec!()));

        // Must return EOF since the underlying reader is empty
        assert!(is_eof(reader.peek()));
    }

    /// Test for the MockReaderWithError helper mock class...
    #[test]
    fn mock_sanity_check() {
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 1);

            // First byte is not a problem.
            assert_eq!(0, reader.read_byte().unwrap());
            // However, now the read fails...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // But, already on the next one, we're out of the woods.
            assert_eq!(0, reader.read_byte().unwrap());
        }
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 0);

            // The read fails on the first one...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // ...but now we're good.
            assert_eq!(0, reader.read_byte().unwrap());
        }
    }

}
<commit_msg>Add tests for when the result of a peek is an `IoError`<commit_after>use std::io::IoResult;

pub struct PeekableReader<R> {
    inner: R,
    peeked_result: Option<IoResult<u8>>,
}

impl<R: Reader> PeekableReader<R> {
    /// Initializes a new `PeekableReader` which wraps the given underlying
    /// reader.
    pub fn new(reader: R) -> PeekableReader<R> {
        PeekableReader {
            inner: reader,
            peeked_result: None,
        }
    }

    pub fn peek(&mut self) -> IoResult<u8> {
        // Return either the currently cached peeked byte or obtain a new one
        // from the underlying reader.
        match self.peeked_result {
            Some(ref old_res) => old_res.clone(),
            None => {
                // First get the result of the read from the underlying reader
                self.peeked_result = Some(self.inner.read_byte());

                // Now just return that
                self.peeked_result.clone().unwrap()
            }
        }
    }
}

impl<R: Reader> Reader for PeekableReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        if buf.len() == 0 {
            return Ok(0);
        }

        // First, put the byte that was read off the underlying reader in a
        // (possible) previous peek operation (if such a byte is indeed cached)
        let offset = match self.peeked_result.clone() {
            Some(Err(e)) => {
                self.peeked_result = None;
                return Err(e);
            },
            Some(Ok(b)) => {
                buf[0] = b;
                self.peeked_result = None;
                1
            },
            None => 0,
        };

        if offset == 1 && buf.len() == 1 {
            // We've filled the buffer by using the previously peeked byte
            Ok(1)
        } else {
            // We are still missing more bytes, so we read them from the
            // underlying reader and place them directly in the correct place
            // in the buffer.
            let (_, leftover) = buf.split_at_mut(offset);
            Ok(try!(self.inner.read(leftover)) + offset)
        }
    }
}

mod tests {
    use super::PeekableReader;
    use std::io::{MemReader, IoError, IoErrorKind, IoResult};

    /// A mock implementation of the `Reader` trait that returns a given
    /// IoError after a certain number of bytes has been read. The error is
    /// returned only once, with subsequent read calls completing successfully
    /// again.
    /// When the Reader successfully reads a byte, it is always `0u8`.
    struct MockReaderWithError {
        error: IoError,
        after: uint,
        bytes_read: uint,
        errored: bool,
    }

    impl MockReaderWithError {
        fn new(error: IoError, after: uint) -> MockReaderWithError {
            MockReaderWithError {
                error: error,
                after: after,
                bytes_read: 0,
                errored: false,
            }
        }
    }

    impl Reader for MockReaderWithError {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            self.bytes_read += buf.len();
            if self.bytes_read <= self.after || self.errored {
                for b in buf.iter_mut() {
                    *b = 0;
                }

                Ok(buf.len())
            } else {
                self.errored = true;
                Err(self.error.clone())
            }
        }
    }

    /// Helper function which checks whether the given result indicated EOF.
    fn is_eof<T>(res: IoResult<T>) -> bool {
        match res {
            Err(IoError {
                kind: IoErrorKind::EndOfFile,
                ..
            }) => true,
            _ => false,
        }
    }

    /// Helper function which just checks whether the given IoResult is equal
    /// to the given IoError.
    fn is_err<T>(err: &IoError, res: IoResult<T>) -> bool {
        match res {
            Err(ref result_error) => result_error == err,
            _ => false,
        }
    }

    /// Tests that it is possible to invoke the `peek` method multiple times
    /// with the same effect, when there are no intermediate reads.
    #[test]
    fn multiple_peeks_idempotent() {
        let b = 1;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b, b + 1)));

        // The first peek is correct?
        assert_eq!(b, reader.peek().unwrap());
        // The second peek (with no reads in between) still returns the same
        // byte?
        assert_eq!(b, reader.peek().unwrap());
    }

    /// Tests that the `peek` method correctly returns an IoError returned by
    /// the underlying reader on consecutive peek calls.
    #[test]
    fn peek_result_error() {
        let err = IoError {
            kind: IoErrorKind::OtherIoError,
            desc: "Dummy error",
            detail: None,
        };
        let mut reader = PeekableReader::new(
            MockReaderWithError::new(err.clone(), 0));

        assert!(is_err(&err, reader.peek()),
                "Expected an IoError!");
        assert!(is_err(&err, reader.peek()),
                "Expected an IoError on the second peek too!");
    }
    #[test]
    fn single_byte_reader_peek() {
        let b = 5u8;
        let mut reader = PeekableReader::new(MemReader::new(vec!(b)));

        // When we peek, we get the correct byte back?
        assert_eq!(b, reader.peek().unwrap());
    }

    #[test]
    fn empty_underlying_reader() {
        let mut reader = PeekableReader::new(MemReader::new(vec!()));

        // Must return EOF since the underlying reader is empty
        assert!(is_eof(reader.peek()));
    }

    /// Test for the MockReaderWithError helper mock class...
    #[test]
    fn mock_sanity_check() {
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 1);

            // First byte is not a problem.
            assert_eq!(0, reader.read_byte().unwrap());
            // However, now the read fails...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // But, already on the next one, we're out of the woods.
            assert_eq!(0, reader.read_byte().unwrap());
        }
        {
            let err = IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "Dummy error",
                detail: None,
            };
            let mut reader = MockReaderWithError::new(err.clone(), 0);

            // The read fails on the first one...
            assert!(is_err(&err, reader.read_byte()),
                    "Expected an IoError on the read byte");
            // ...but now we're good.
            assert_eq!(0, reader.read_byte().unwrap());
        }
    }

}
<|endoftext|>


<commit_before>//! A crate that provides the `IpAddr` type, which can represent either an IPv4
//! or an IPv6 address.

use std::fmt;
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;

/// An IP address, either an IPv4 or IPv6 address.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpAddr {
    /// Representation of an IPv4 address.
    V4(Ipv4Addr),
    /// Representation of an IPv6 address.
    V6(Ipv6Addr),
}

impl fmt::Display for IpAddr {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpAddr::V4(ref a) => a.fmt(fmt),
            IpAddr::V6(ref a) => a.fmt(fmt),
        }
    }
}

impl FromStr for IpAddr {
    type Err = AddrParseError;

    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Ipv4Addr::from_str(s).map(|v4| IpAddr::V4(v4))
            .or_else(|_| {
                Ipv6Addr::from_str(s).map(|v6| IpAddr::V6(v6))
            })
    }
}

#[test]
fn parse_ipv4() {
    let parsed = IpAddr::from_str("192.168.0.1").unwrap();
    let ipv4 = Ipv4Addr::from_str("192.168.0.1").unwrap();
    assert_eq!(IpAddr::V4(ipv4), parsed);
}

#[test]
fn parse_ipv6() {
    let parsed = IpAddr::from_str("2001:0db8::0001").unwrap();
    let ipv6 = Ipv6Addr::from_str("2001:0db8::0001").unwrap();
    assert_eq!(IpAddr::V6(ipv6), parsed);
}
<commit_msg>Add a testcase for a failing parse<commit_after>//! A crate that provides the `IpAddr` type, which can represent either an IPv4
//! or an IPv6 address.

use std::fmt;
use std::net::{AddrParseError, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;

/// An IP address, either an IPv4 or IPv6 address.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpAddr {
    /// Representation of an IPv4 address.
    V4(Ipv4Addr),
    /// Representation of an IPv6 address.
    V6(Ipv6Addr),
}

impl fmt::Display for IpAddr {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpAddr::V4(ref a) => a.fmt(fmt),
            IpAddr::V6(ref a) => a.fmt(fmt),
        }
    }
}

impl FromStr for IpAddr {
    type Err = AddrParseError;

    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Ipv4Addr::from_str(s).map(|v4| IpAddr::V4(v4))
            .or_else(|_| {
                Ipv6Addr::from_str(s).map(|v6| IpAddr::V6(v6))
            })
    }
}

#[test]
fn parse_ipv4() {
    let parsed = IpAddr::from_str("192.168.0.1").unwrap();
    let ipv4 = Ipv4Addr::from_str("192.168.0.1").unwrap();
    assert_eq!(IpAddr::V4(ipv4), parsed);
}

#[test]
fn parse_ipv6() {
    let parsed = IpAddr::from_str("2001:0db8::0001").unwrap();
    let ipv6 = Ipv6Addr::from_str("2001:0db8::0001").unwrap();
    assert_eq!(IpAddr::V6(ipv6), parsed);
}

#[test]
fn parse_fails() {
    let parsed = IpAddr::from_str("nonsense");
    assert!(parsed.is_err());
}
<|endoftext|>


<commit_before>#![feature(try_from)]

extern crate byteorder;
#[macro_use]
extern crate serde;

pub mod error;
pub mod de;
pub mod ser;
<commit_msg>Export to_vec, from_vec, etc at toplevel<commit_after>#![feature(try_from)]

extern crate byteorder;
#[macro_use]
extern crate serde;

pub mod error;
pub mod de;
pub mod ser;

pub use de::{from_read, from_vec};
pub use ser::{to_write, to_vec};
<|endoftext|>


<commit_before>extern crate regex;
extern crate chrono;

use crate::command_executor::{Command, CommandContext, CommandMetadata, CommandParams, CommandGroup, CommandGroupMetadata, DynamicCompletionType};
use crate::commands::*;

use indy::{ErrorCode, IndyError};
use crate::libindy::payment::Payment;

use serde_json::Value as JSONValue;
use serde_json::Map as JSONMap;

use crate::utils::table::print_list_table;

pub mod group {
    use super::*;

    command_group!(CommandGroupMetadata::new("payment-address", "Payment address management commands"));
}

pub mod new_command {
    use super::*;

    command!(CommandMetadata::build("new", "Create the payment address for specified payment method.")
                .add_required_param("payment_method", "Payment method to use")
                .add_optional_param("seed", "Seed for creating payment address")
                .add_example("payment-address create payment_method=sov")
                .add_example("payment-address create payment_method=sov seed=000000000000000000000000000Seed1")
                .finalize()
    );

    pub(super) fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let payment_method = get_str_param("payment_method", params).map_err(error_err!())?;
        let seed = get_opt_str_param("seed", params).map_err(error_err!())?;

        let config = {
            let mut json = JSONMap::new();
            update_json_map_opt_key!(json, "seed", seed);
            JSONValue::from(json).to_string()
        };

        let res = match Payment::create_payment_address(wallet_handle, payment_method, &config) {
            Ok(payment_address) => {
                println_succ!("Payment Address has been created \"{}\"", payment_address);
                Ok(())
            },
            Err(err) => {
                handle_payment_error(err, Some(payment_method));
                Err(())
            },
        };

        trace!("execute << {:?}", res);
        res
    }
}

pub mod create_command {
    use super::*;

    command!(CommandMetadata::build("create", r#"Create the payment address for specified payment method.

        Take note that this command will be removed in one of the future releases in favor `payment-address new` command."#)
                .add_required_param("payment_method", "Payment method to use")
                .add_optional_param("seed", "Seed for creating payment address")
                .add_example("payment-address create payment_method=sov")
                .add_example("payment-address create payment_method=sov seed=000000000000000000000000000Seed1")
                .finalize()
    );

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        new_command::execute(ctx, params)
    }
}

pub mod list_command {
    use super::*;

    command!(CommandMetadata::build("list", "Lists all payment addresses that are stored in the wallet.")
                .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let res = match Payment::list_payment_addresses(wallet_handle) {
            Ok(payment_addresses_json) => {
                let payment_addresses: Vec<String> = serde_json::from_str(&payment_addresses_json)
                    .map_err(|_| println_err!("Wrong data has been received"))?;

                let list_addresses =
                    payment_addresses.iter()
                        .map(|payment_address| {
                            let parts = payment_address.split(':').collect::<Vec<&str>>();
                            json!({
                                "address": payment_address,
                                "method": parts.get(1).unwrap_or(&"Unknown payment method")
                            })
                        })
                        .collect::<Vec<serde_json::Value>>();

                print_list_table(&list_addresses,
                                 &[("address", "Payment Address"),
                                     ("method", "Payment Method")],
                                 "There are no payment addresses");
                Ok(())
            }
            Err(err) => {
                handle_indy_error(err, None, None, None);
                Err(())
            },
        };

        trace!("execute << {:?}", res);
        res
    }
}

pub mod sign_command {
    use super::*;

    command!(CommandMetadata::build("sign", "Create a proof of payment address control by signing an input and producing a signature.")
                .add_required_param_with_dynamic_completion("address","Payment address to use", DynamicCompletionType::PaymentAddress)
                .add_required_param("input", "The input data to be signed")
                .add_example("payment-address sign address=pay:null:lUdSMj9AmoUbmRQ input=123456789")
                .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let address = get_str_param("address", params).map_err(error_err!())?;
        let input = get_str_param("input", params).map_err(error_err!())?;

        let res = match Payment::sign_with_address(wallet_handle, address, input) {
            Ok(signature) => Ok(println_succ!("Signature \"0x{}\"", bin2hex(signature.as_slice()))),
            Err(err) => Err(handle_indy_error(err, None, None, None))
        };

        trace!("execute << {:?}", res);
        res
    }

    fn bin2hex(b: &[u8]) -> String {
        b.iter()
            .map(|b| format!("{:02x}", b))
            .collect::<Vec<_>>()
            .join("")
    }
}

pub mod verify_command {
    use super::*;

    command!(CommandMetadata::build("verify", "Verify a proof of payment address control by verifying a signature.")
             .add_required_param_with_dynamic_completion("address","Payment address to use", DynamicCompletionType::PaymentAddress)
             .add_required_param("input", "The input data that was signed")
             .add_required_param("signature", "The signature generated from sign-with-address")
             .add_example("payment-address verify address=pay:null:lUdSMj9AmoUbmRQ input=123456789 signature=0x0006e83221cdaf70b3c01a613675274dd2064ea376bf35656cff8436e62cdf89")
             .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let address = get_str_param("address", params).map_err(error_err!())?;
        let input = get_str_param("input", params).map_err(error_err!())?;
        let signature = get_str_param("signature", params).map_err(error_err!())?;

        if &signature[0..2] != "0x" {
            println_err!("Wrong data has been received. Expected signature to start with '0x'");
            return Err(());
        }

        let sig = hex2bin(&signature[2..]).map_err(|e| println_err!("{}", e))?;

        let res = match Payment::verify_with_address(address, input, sig.as_slice()) {
            Ok(valid) => {
                if valid {
                    Ok(println_succ!("Valid signature"))
                } else {
                    Ok(println_err!("Invalid signature"))
                }
            }
            Err(err) => Err(handle_indy_error(err, None, None, None))
        };

        trace!("execute << {:?}", res);
        res
    }

    fn hex2bin(s: &str) -> Result<Vec<u8>, String> {
        if s.len() % 2 != 0 {
            return Err("Bad input".to_string());
        }
        for (i, ch) in s.chars().enumerate() {
            if !ch.is_digit(16) {
                return Err(format!(
                    "Bad character position {}",
                    i
                ));
            }
        }

        let input: Vec<_> = s.chars().collect();

        let decoded: Vec<u8> = input
            .chunks(2)
            .map(|chunk| {
                ((chunk[0].to_digit(16).unwrap() << 4) | (chunk[1].to_digit(16).unwrap())) as u8
            })
            .collect();

        Ok(decoded)
    }
}

pub fn handle_payment_error(err: IndyError, payment_method: Option<&str>) {
    match err.error_code {
        ErrorCode::UnknownPaymentMethod => println_err!("Unknown payment method {}", payment_method.unwrap_or("")),
        ErrorCode::IncompatiblePaymentError => println_err!("No methods were scraped or more than one was scraped"),
        ErrorCode::PaymentInsufficientFundsError => println_err!("Insufficient funds on inputs"),
        ErrorCode::PaymentExtraFundsError => println_err!("Extra funds on inputs"),
        ErrorCode::PaymentSourceDoesNotExistError => println_err!("Payment source not found"),
        ErrorCode::PaymentOperationNotSupportedError => println_err!("Payment operation not supported"),
        ErrorCode::WalletItemAlreadyExists => println_err!("Payment address already exists"),
        _ => println_err!("{}", err.message)
    }
}

pub fn list_payment_addresses(ctx: &CommandContext) -> Vec<String> {
    get_opened_wallet(ctx)
        .and_then(|(wallet_handle, _)|
            Payment::list_payment_addresses(wallet_handle).ok()
        )
        .and_then(|payment_addresses|
            serde_json::from_str(&payment_addresses).ok()
        )
        .unwrap_or_default()
}

#[cfg(test)]
#[cfg(feature = "nullpay_plugin")]
pub mod tests {
    use super::*;
    use crate::commands::common::tests::{load_null_payment_plugin, NULL_PAYMENT_METHOD};
    use crate::commands::did::tests::SEED_MY1;

    pub const INPUT: &str = "123456789";

    mod new {
        use super::*;

        #[test]
        pub fn new_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());
            assert!(addresses[0].starts_with("pay:null:"));

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_seed() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                params.insert("seed", SEED_MY1.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());
            //            assert_eq!("pay:null:AkQr7K6CP1tslXd", addresses[0]);  TODO: Exactly check

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_unknown_payment_method() {
            let ctx = setup_with_wallet();
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", "unknown_payment_method".to_string());
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_no_opened_wallet() {
            let ctx = setup();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down();
        }
    }

    mod list {
        use super::*;

        #[test]
        pub fn list_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            create_payment_address(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn list_works_for_empty_list() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(0, addresses.len());

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn list_works_for_no_opened_wallet() {
            let ctx = setup();
            load_null_payment_plugin(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down();
        }
    }

    mod sign {
        use super::*;

        #[test]
        pub fn sign_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            let payment_address = create_payment_address(&ctx);
            {
                let cmd = sign_command::new();
                let mut params = CommandParams::new();
                params.insert("address", payment_address);
                params.insert("input", INPUT.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }
    }

    mod verify {
        use super::*;

        const PAYMENT_ADDRESS: &str = "pay:null:lUdSMj9AmoUbmRQ";

        #[test]
        pub fn verify_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = verify_command::new();
                let mut params = CommandParams::new();
                params.insert("address", PAYMENT_ADDRESS.to_string());
                params.insert("input", INPUT.to_string());
                params.insert("signature", "0x0006e83221cdaf70b3c01a613675274dd2064ea376bf35656cff8436e62cdf89".to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn verify_works_for_invalid_signature() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = verify_command::new();
                let mut params = CommandParams::new();
                params.insert("address", PAYMENT_ADDRESS.to_string());
                params.insert("input", INPUT.to_string());
                params.insert("signature", "0x0006e83221cdaf70b3c01a613675274dd2064ea376bf11111111111111111111".to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }
    }

    pub fn create_payment_address(ctx: &CommandContext) -> String {
        let wallet_handle = ensure_opened_wallet_handle(ctx).unwrap();
        Payment::create_payment_address(wallet_handle, NULL_PAYMENT_METHOD, "{}").unwrap()
    }
}
<commit_msg>IS-1415: Corrected help for Payment address new  command<commit_after>extern crate regex;
extern crate chrono;

use crate::command_executor::{Command, CommandContext, CommandMetadata, CommandParams, CommandGroup, CommandGroupMetadata, DynamicCompletionType};
use crate::commands::*;

use indy::{ErrorCode, IndyError};
use crate::libindy::payment::Payment;

use serde_json::Value as JSONValue;
use serde_json::Map as JSONMap;

use crate::utils::table::print_list_table;

pub mod group {
    use super::*;

    command_group!(CommandGroupMetadata::new("payment-address", "Payment address management commands"));
}

pub mod new_command {
    use super::*;

    command!(CommandMetadata::build("new", "Create the payment address for specified payment method.")
                .add_required_param("payment_method", "Payment method to use")
                .add_optional_param("seed", "Seed for creating payment address")
                .add_example("payment-address new payment_method=sov")
                .add_example("payment-address new payment_method=sov seed=000000000000000000000000000Seed1")
                .finalize()
    );

    pub(super) fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let payment_method = get_str_param("payment_method", params).map_err(error_err!())?;
        let seed = get_opt_str_param("seed", params).map_err(error_err!())?;

        let config = {
            let mut json = JSONMap::new();
            update_json_map_opt_key!(json, "seed", seed);
            JSONValue::from(json).to_string()
        };

        let res = match Payment::create_payment_address(wallet_handle, payment_method, &config) {
            Ok(payment_address) => {
                println_succ!("Payment Address has been created \"{}\"", payment_address);
                Ok(())
            },
            Err(err) => {
                handle_payment_error(err, Some(payment_method));
                Err(())
            },
        };

        trace!("execute << {:?}", res);
        res
    }
}

pub mod create_command {
    use super::*;

    command!(CommandMetadata::build("create", r#"Create the payment address for specified payment method. TAKE NOTE that this command will be removed in one of the future releases in favor `payment-address new` command."#)
                .add_required_param("payment_method", "Payment method to use")
                .add_optional_param("seed", "Seed for creating payment address")
                .add_example("payment-address create payment_method=sov")
                .add_example("payment-address create payment_method=sov seed=000000000000000000000000000Seed1")
                .finalize()
    );

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        new_command::execute(ctx, params)
    }
}

pub mod list_command {
    use super::*;

    command!(CommandMetadata::build("list", "Lists all payment addresses that are stored in the wallet.")
                .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let res = match Payment::list_payment_addresses(wallet_handle) {
            Ok(payment_addresses_json) => {
                let payment_addresses: Vec<String> = serde_json::from_str(&payment_addresses_json)
                    .map_err(|_| println_err!("Wrong data has been received"))?;

                let list_addresses =
                    payment_addresses.iter()
                        .map(|payment_address| {
                            let parts = payment_address.split(':').collect::<Vec<&str>>();
                            json!({
                                "address": payment_address,
                                "method": parts.get(1).unwrap_or(&"Unknown payment method")
                            })
                        })
                        .collect::<Vec<serde_json::Value>>();

                print_list_table(&list_addresses,
                                 &[("address", "Payment Address"),
                                     ("method", "Payment Method")],
                                 "There are no payment addresses");
                Ok(())
            }
            Err(err) => {
                handle_indy_error(err, None, None, None);
                Err(())
            },
        };

        trace!("execute << {:?}", res);
        res
    }
}

pub mod sign_command {
    use super::*;

    command!(CommandMetadata::build("sign", "Create a proof of payment address control by signing an input and producing a signature.")
                .add_required_param_with_dynamic_completion("address","Payment address to use", DynamicCompletionType::PaymentAddress)
                .add_required_param("input", "The input data to be signed")
                .add_example("payment-address sign address=pay:null:lUdSMj9AmoUbmRQ input=123456789")
                .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let wallet_handle = ensure_opened_wallet_handle(&ctx)?;

        let address = get_str_param("address", params).map_err(error_err!())?;
        let input = get_str_param("input", params).map_err(error_err!())?;

        let res = match Payment::sign_with_address(wallet_handle, address, input) {
            Ok(signature) => Ok(println_succ!("Signature \"0x{}\"", bin2hex(signature.as_slice()))),
            Err(err) => Err(handle_indy_error(err, None, None, None))
        };

        trace!("execute << {:?}", res);
        res
    }

    fn bin2hex(b: &[u8]) -> String {
        b.iter()
            .map(|b| format!("{:02x}", b))
            .collect::<Vec<_>>()
            .join("")
    }
}

pub mod verify_command {
    use super::*;

    command!(CommandMetadata::build("verify", "Verify a proof of payment address control by verifying a signature.")
             .add_required_param_with_dynamic_completion("address","Payment address to use", DynamicCompletionType::PaymentAddress)
             .add_required_param("input", "The input data that was signed")
             .add_required_param("signature", "The signature generated from sign-with-address")
             .add_example("payment-address verify address=pay:null:lUdSMj9AmoUbmRQ input=123456789 signature=0x0006e83221cdaf70b3c01a613675274dd2064ea376bf35656cff8436e62cdf89")
             .finalize());

    fn execute(ctx: &CommandContext, params: &CommandParams) -> Result<(), ()> {
        trace!("execute >> ctx {:?} params {:?}", ctx, params);

        let address = get_str_param("address", params).map_err(error_err!())?;
        let input = get_str_param("input", params).map_err(error_err!())?;
        let signature = get_str_param("signature", params).map_err(error_err!())?;

        if &signature[0..2] != "0x" {
            println_err!("Wrong data has been received. Expected signature to start with '0x'");
            return Err(());
        }

        let sig = hex2bin(&signature[2..]).map_err(|e| println_err!("{}", e))?;

        let res = match Payment::verify_with_address(address, input, sig.as_slice()) {
            Ok(valid) => {
                if valid {
                    Ok(println_succ!("Valid signature"))
                } else {
                    Ok(println_err!("Invalid signature"))
                }
            }
            Err(err) => Err(handle_indy_error(err, None, None, None))
        };

        trace!("execute << {:?}", res);
        res
    }

    fn hex2bin(s: &str) -> Result<Vec<u8>, String> {
        if s.len() % 2 != 0 {
            return Err("Bad input".to_string());
        }
        for (i, ch) in s.chars().enumerate() {
            if !ch.is_digit(16) {
                return Err(format!(
                    "Bad character position {}",
                    i
                ));
            }
        }

        let input: Vec<_> = s.chars().collect();

        let decoded: Vec<u8> = input
            .chunks(2)
            .map(|chunk| {
                ((chunk[0].to_digit(16).unwrap() << 4) | (chunk[1].to_digit(16).unwrap())) as u8
            })
            .collect();

        Ok(decoded)
    }
}

pub fn handle_payment_error(err: IndyError, payment_method: Option<&str>) {
    match err.error_code {
        ErrorCode::UnknownPaymentMethod => println_err!("Unknown payment method {}", payment_method.unwrap_or("")),
        ErrorCode::IncompatiblePaymentError => println_err!("No methods were scraped or more than one was scraped"),
        ErrorCode::PaymentInsufficientFundsError => println_err!("Insufficient funds on inputs"),
        ErrorCode::PaymentExtraFundsError => println_err!("Extra funds on inputs"),
        ErrorCode::PaymentSourceDoesNotExistError => println_err!("Payment source not found"),
        ErrorCode::PaymentOperationNotSupportedError => println_err!("Payment operation not supported"),
        ErrorCode::WalletItemAlreadyExists => println_err!("Payment address already exists"),
        _ => println_err!("{}", err.message)
    }
}

pub fn list_payment_addresses(ctx: &CommandContext) -> Vec<String> {
    get_opened_wallet(ctx)
        .and_then(|(wallet_handle, _)|
            Payment::list_payment_addresses(wallet_handle).ok()
        )
        .and_then(|payment_addresses|
            serde_json::from_str(&payment_addresses).ok()
        )
        .unwrap_or_default()
}

#[cfg(test)]
#[cfg(feature = "nullpay_plugin")]
pub mod tests {
    use super::*;
    use crate::commands::common::tests::{load_null_payment_plugin, NULL_PAYMENT_METHOD};
    use crate::commands::did::tests::SEED_MY1;

    pub const INPUT: &str = "123456789";

    mod new {
        use super::*;

        #[test]
        pub fn new_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());
            assert!(addresses[0].starts_with("pay:null:"));

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_seed() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                params.insert("seed", SEED_MY1.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());
            //            assert_eq!("pay:null:AkQr7K6CP1tslXd", addresses[0]);  TODO: Exactly check

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_unknown_payment_method() {
            let ctx = setup_with_wallet();
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", "unknown_payment_method".to_string());
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn new_works_for_no_opened_wallet() {
            let ctx = setup();
            load_null_payment_plugin(&ctx);
            {
                let cmd = new_command::new();
                let mut params = CommandParams::new();
                params.insert("payment_method", NULL_PAYMENT_METHOD.to_string());
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down();
        }
    }

    mod list {
        use super::*;

        #[test]
        pub fn list_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            create_payment_address(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(1, addresses.len());

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn list_works_for_empty_list() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap();
            }
            let addresses = list_payment_addresses(&ctx);
            assert_eq!(0, addresses.len());

            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn list_works_for_no_opened_wallet() {
            let ctx = setup();
            load_null_payment_plugin(&ctx);
            {
                let cmd = list_command::new();
                let params = CommandParams::new();
                cmd.execute(&ctx, &params).unwrap_err();
            }
            tear_down();
        }
    }

    mod sign {
        use super::*;

        #[test]
        pub fn sign_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            let payment_address = create_payment_address(&ctx);
            {
                let cmd = sign_command::new();
                let mut params = CommandParams::new();
                params.insert("address", payment_address);
                params.insert("input", INPUT.to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }
    }

    mod verify {
        use super::*;

        const PAYMENT_ADDRESS: &str = "pay:null:lUdSMj9AmoUbmRQ";

        #[test]
        pub fn verify_works() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = verify_command::new();
                let mut params = CommandParams::new();
                params.insert("address", PAYMENT_ADDRESS.to_string());
                params.insert("input", INPUT.to_string());
                params.insert("signature", "0x0006e83221cdaf70b3c01a613675274dd2064ea376bf35656cff8436e62cdf89".to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }

        #[test]
        pub fn verify_works_for_invalid_signature() {
            let ctx = setup_with_wallet();
            load_null_payment_plugin(&ctx);
            {
                let cmd = verify_command::new();
                let mut params = CommandParams::new();
                params.insert("address", PAYMENT_ADDRESS.to_string());
                params.insert("input", INPUT.to_string());
                params.insert("signature", "0x0006e83221cdaf70b3c01a613675274dd2064ea376bf11111111111111111111".to_string());
                cmd.execute(&ctx, &params).unwrap();
            }
            tear_down_with_wallet(&ctx);
        }
    }

    pub fn create_payment_address(ctx: &CommandContext) -> String {
        let wallet_handle = ensure_opened_wallet_handle(ctx).unwrap();
        Payment::create_payment_address(wallet_handle, NULL_PAYMENT_METHOD, "{}").unwrap()
    }
}
<|endoftext|>


<commit_before>use std::ops::Not;

use types::*;
use requests::*;

/// Use this method to send point on the map.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct SendLocation<'c> {
    chat_id: ChatRef<'c>,
    latitude: Float,
    longitude: Float,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_to_message_id: Option<MessageId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_markup: Option<ReplyMarkup>,
}

impl<'c> Request for SendLocation<'c> {
    type Response = Message;
    type RawResponse = Message;

    fn map(raw: Self::RawResponse) -> Self::Response {
        raw
    }

    fn name() -> &'static str {
        "sendLocation"
    }
}

impl<'c> SendLocation<'c> {
    pub fn new<C>(chat: C, latitude: Float, longitude: Float) -> Self where C: ToChatRef<'c> {
        SendLocation {
            chat_id: chat.to_chat_ref(),
            latitude: latitude,
            longitude: longitude,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(mut self, to: R) -> Self where R: ToMessageId {
        self.reply_to_message_id = Some(to.to_message_id());
        self
    }

    pub fn reply_markup<R>(mut self, reply_markup: R) -> Self where R: Into<ReplyMarkup> { // TODO(knsd): nice builder?
        self.reply_markup = Some(reply_markup.into());
        self
    }
}

pub trait CanSendLocation<'c> {
    fn location(&self, latitude: Float, longitude: Float) -> SendLocation<'c>;
}

impl<'c, C> CanSendLocation<'c> for C where C: ToChatRef<'c> {
    fn location(&self, latitude: Float, longitude: Float) -> SendLocation<'c> {
        SendLocation::new(self, latitude, longitude)
    }
}

pub trait CanReplySendLocation {
    fn location_reply<'c>(&self, latitude: Float, longitude: Float) -> SendLocation<'c>;
}

impl CanReplySendLocation for Message {
    fn location_reply<'c>(&self, latitude: Float, longitude: Float) -> SendLocation<'c> {
        self.chat.location(latitude, longitude).reply_to(self)
    }
}

impl<'b, 'c> ToRequest<'b, 'c> for Location {
    type Request = SendLocation<'c>;

    fn to_request<C>(&'b self, chat: C) -> Self::Request where C: ToChatRef<'c> {
        chat.location(self.latitude, self.longitude)
    }
}

impl<'b, 'c> ToReplyRequest<'b, 'c> for Location {
    type Request = SendLocation<'c>;

    fn to_reply_request(&'b self, message: &Message) -> Self::Request {
        message.location_reply(self.latitude, self.longitude)
    }
}
<commit_msg>refactor: implement CanReplySendLocation for ToMessageId + ToSourceChat<commit_after>use std::ops::Not;

use types::*;
use requests::*;

/// Use this method to send point on the map.
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct SendLocation<'c> {
    chat_id: ChatRef<'c>,
    latitude: Float,
    longitude: Float,
    #[serde(skip_serializing_if = "Not::not")]
    disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_to_message_id: Option<MessageId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    reply_markup: Option<ReplyMarkup>,
}

impl<'c> Request for SendLocation<'c> {
    type Response = Message;
    type RawResponse = Message;

    fn map(raw: Self::RawResponse) -> Self::Response {
        raw
    }

    fn name() -> &'static str {
        "sendLocation"
    }
}

impl<'c> SendLocation<'c> {
    pub fn new<C>(chat: C, latitude: Float, longitude: Float) -> Self where C: ToChatRef<'c> {
        SendLocation {
            chat_id: chat.to_chat_ref(),
            latitude: latitude,
            longitude: longitude,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(mut self, to: R) -> Self where R: ToMessageId {
        self.reply_to_message_id = Some(to.to_message_id());
        self
    }

    pub fn reply_markup<R>(mut self, reply_markup: R) -> Self where R: Into<ReplyMarkup> { // TODO(knsd): nice builder?
        self.reply_markup = Some(reply_markup.into());
        self
    }
}

pub trait CanSendLocation<'c> {
    fn location(&self, latitude: Float, longitude: Float) -> SendLocation<'c>;
}

impl<'c, C> CanSendLocation<'c> for C where C: ToChatRef<'c> {
    fn location(&self, latitude: Float, longitude: Float) -> SendLocation<'c> {
        SendLocation::new(self, latitude, longitude)
    }
}

pub trait CanReplySendLocation {
    fn location_reply<'c>(&self, latitude: Float, longitude: Float) -> SendLocation<'c>;
}

impl<M> CanReplySendLocation for M where M: ToMessageId + ToSourceChat {
    fn location_reply<'c>(&self, latitude: Float, longitude: Float) -> SendLocation<'c> {
        self.to_source_chat().location(latitude, longitude).reply_to(self.to_message_id())
    }
}

impl<'b, 'c> ToRequest<'b, 'c> for Location {
    type Request = SendLocation<'c>;

    fn to_request<C>(&'b self, chat: C) -> Self::Request where C: ToChatRef<'c> {
        chat.location(self.latitude, self.longitude)
    }
}

impl<'b, 'c> ToReplyRequest<'b, 'c> for Location {
    type Request = SendLocation<'c>;

    fn to_reply_request(&'b self, message: &Message) -> Self::Request {
        message.location_reply(self.latitude, self.longitude)
    }
}
<|endoftext|>


<commit_before>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("analysis");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) or (home_id = ?2 and away_id = ?1) \
                      and dato > date('now','start of month') ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    print!("{:?}", map);

//      p1  mål     p1 vundne   p1 navn     p1 antal kampe
//      p2  mål     p2 vundne   p2 navn     p2 antal kampe

    let mut context = create_context("analysis");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<commit_msg>Highlight the right menu item on /pvp<commit_after>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("pvp");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) or (home_id = ?2 and away_id = ?1) \
                      and dato > date('now','start of month') ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    print!("{:?}", map);

//      p1  mål     p1 vundne   p1 navn     p1 antal kampe
//      p2  mål     p2 vundne   p2 navn     p2 antal kampe

    let mut context = create_context("analysis");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use rustc::ty;
use rustc::hir::*;
use utils::{match_def_path, paths, span_note_and_lint, is_copy};

/// **What it does:** Checks for calls to `std::mem::drop` with a reference
/// instead of an owned value.
///
/// **Why is this bad?** Calling `drop` on a reference will only drop the
/// reference itself, which is a no-op. It will not call the `drop` method (from
/// the `Drop` trait implementation) on the underlying referenced value, which
/// is likely what was intended.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let mut lock_guard = mutex.lock();
/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex still locked
/// operation_that_requires_mutex_to_be_unlocked();
/// ```
declare_lint! {
    pub DROP_REF,
    Warn,
    "calls to `std::mem::drop` with a reference instead of an owned value"
}

/// **What it does:** Checks for calls to `std::mem::forget` with a reference
/// instead of an owned value.
///
/// **Why is this bad?** Calling `forget` on a reference will only forget the
/// reference itself, which is a no-op. It will not forget the underlying referenced
/// value, which is likely what was intended.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x = Box::new(1);
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
/// ```
declare_lint! {
    pub FORGET_REF,
    Warn,
    "calls to `std::mem::forget` with a reference instead of an owned value"
}

/// **What it does:** Checks for calls to `std::mem::drop` with a value
/// that derives the Copy trait
///
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
/// value will be copied and moved into the function on invocation.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x:i32 = 42;   // i32 implements Copy
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the original unaffected
/// ```
declare_lint! {
    pub DROP_COPY,
    Warn,
    "calls to `std::mem::drop` with a value that implements Copy"
}

/// **What it does:** Checks for calls to `std::mem::forget` with a value that
/// derives the Copy trait
///
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
/// value will be copied and moved into the function on invocation.
///
/// An alternative, but also valid, explanation is that Copy types do not implement
/// the Drop trait, which means they have no destructors. Without a destructor, there
/// is nothing for `std::mem::forget` to ignore.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x:i32 = 42;     // i32 implements Copy
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the original unaffected
/// ```
declare_lint! {
    pub FORGET_COPY,
    Warn,
    "calls to `std::mem::forget` with a value that implements Copy"
}

const DROP_REF_SUMMARY:&str = "calls to `std::mem::drop` with a reference instead of an owned value. \
                               Dropping a reference does nothing.";
const FORGET_REF_SUMMARY:&str = "calls to `std::mem::forget` with a reference instead of an owned value. \
                                 Forgetting a reference does nothing.";
const DROP_COPY_SUMMARY:&str = "calls to `std::mem::drop` with a value that implements Copy. \
                                Dropping a copy leaves the original intact.";
const FORGET_COPY_SUMMARY:&str = "calls to `std::mem::forget` with a value that implements Copy. \
                                  Forgetting a copy leaves the original intact.";

#[allow(missing_copy_implementations)]
pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(DROP_REF, FORGET_REF)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        if_let_chain!{[
            let ExprCall(ref path, ref args) = expr.node,
            let ExprPath(ref qpath) = path.node,
            args.len() == 1,
        ], {
            let def_id = cx.tables.qpath_def(qpath, path.id).def_id();
            let lint;
            let msg;
            let arg = &args[0];
            let arg_ty = cx.tables.expr_ty(arg);

            if let ty::TyRef(..) = arg_ty.sty {
                if match_def_path(cx.tcx, def_id, &paths::DROP) {
                    lint = DROP_REF;
                    msg = DROP_REF_SUMMARY.to_string();
                } else if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
                    lint = FORGET_REF;
                    msg = FORGET_REF_SUMMARY.to_string();
                } else {
                    return;
                }
                span_note_and_lint(cx,
                                   lint,
                                   expr.span,
                                   &msg,
                                   arg.span,
                                   &format!("argument has type {}", arg_ty.sty));
            } else if is_copy(cx, arg_ty, cx.tcx.hir.get_parent(arg.id)) {
                if match_def_path(cx.tcx, def_id, &paths::DROP) {
                    lint = DROP_COPY;
                    msg = DROP_COPY_SUMMARY.to_string();
                } else if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
                    lint = FORGET_COPY;
                    msg = FORGET_COPY_SUMMARY.to_string();
                } else {
                    return;
                }
                span_note_and_lint(cx,
                                   lint,
                                   expr.span,
                                   &msg,
                                   arg.span,
                                   &format!("argument has type {}", arg_ty.sty));
            }
        }}
    }
}
<commit_msg>Add space between colon and type annotation Wrapped string in Rust don't require a backslash<commit_after>use rustc::lint::*;
use rustc::ty;
use rustc::hir::*;
use utils::{match_def_path, paths, span_note_and_lint, is_copy};

/// **What it does:** Checks for calls to `std::mem::drop` with a reference
/// instead of an owned value.
///
/// **Why is this bad?** Calling `drop` on a reference will only drop the
/// reference itself, which is a no-op. It will not call the `drop` method (from
/// the `Drop` trait implementation) on the underlying referenced value, which
/// is likely what was intended.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let mut lock_guard = mutex.lock();
/// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex still locked
/// operation_that_requires_mutex_to_be_unlocked();
/// ```
declare_lint! {
    pub DROP_REF,
    Warn,
    "calls to `std::mem::drop` with a reference instead of an owned value"
}

/// **What it does:** Checks for calls to `std::mem::forget` with a reference
/// instead of an owned value.
///
/// **Why is this bad?** Calling `forget` on a reference will only forget the
/// reference itself, which is a no-op. It will not forget the underlying referenced
/// value, which is likely what was intended.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x = Box::new(1);
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
/// ```
declare_lint! {
    pub FORGET_REF,
    Warn,
    "calls to `std::mem::forget` with a reference instead of an owned value"
}

/// **What it does:** Checks for calls to `std::mem::drop` with a value
/// that derives the Copy trait
///
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
/// value will be copied and moved into the function on invocation.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x:i32 = 42;   // i32 implements Copy
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the original unaffected
/// ```
declare_lint! {
    pub DROP_COPY,
    Warn,
    "calls to `std::mem::drop` with a value that implements Copy"
}

/// **What it does:** Checks for calls to `std::mem::forget` with a value that
/// derives the Copy trait
///
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
/// value will be copied and moved into the function on invocation.
///
/// An alternative, but also valid, explanation is that Copy types do not implement
/// the Drop trait, which means they have no destructors. Without a destructor, there
/// is nothing for `std::mem::forget` to ignore.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let x:i32 = 42;     // i32 implements Copy
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the original unaffected
/// ```
declare_lint! {
    pub FORGET_COPY,
    Warn,
    "calls to `std::mem::forget` with a value that implements Copy"
}

const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value.
                               Dropping a reference does nothing.";
const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value.
                                 Forgetting a reference does nothing.";
const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements Copy.
                                Dropping a copy leaves the original intact.";
const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements Copy.
                                  Forgetting a copy leaves the original intact.";

#[allow(missing_copy_implementations)]
pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(DROP_REF, FORGET_REF)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        if_let_chain!{[
            let ExprCall(ref path, ref args) = expr.node,
            let ExprPath(ref qpath) = path.node,
            args.len() == 1,
        ], {
            let def_id = cx.tables.qpath_def(qpath, path.id).def_id();
            let lint;
            let msg;
            let arg = &args[0];
            let arg_ty = cx.tables.expr_ty(arg);

            if let ty::TyRef(..) = arg_ty.sty {
                if match_def_path(cx.tcx, def_id, &paths::DROP) {
                    lint = DROP_REF;
                    msg = DROP_REF_SUMMARY.to_string();
                } else if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
                    lint = FORGET_REF;
                    msg = FORGET_REF_SUMMARY.to_string();
                } else {
                    return;
                }
                span_note_and_lint(cx,
                                   lint,
                                   expr.span,
                                   &msg,
                                   arg.span,
                                   &format!("argument has type {}", arg_ty.sty));
            } else if is_copy(cx, arg_ty, cx.tcx.hir.get_parent(arg.id)) {
                if match_def_path(cx.tcx, def_id, &paths::DROP) {
                    lint = DROP_COPY;
                    msg = DROP_COPY_SUMMARY.to_string();
                } else if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
                    lint = FORGET_COPY;
                    msg = FORGET_COPY_SUMMARY.to_string();
                } else {
                    return;
                }
                span_note_and_lint(cx,
                                   lint,
                                   expr.span,
                                   &msg,
                                   arg.span,
                                   &format!("argument has type {}", arg_ty.sty));
            }
        }}
    }
}
<|endoftext|>


<commit_before>use crate::utils::span_lint;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for needlessly including a base struct on update
    /// when all fields are changed anyway.
    ///
    /// **Why is this bad?** This will cost resources (because the base has to be
    /// somewhere), and make the code less readable.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// # struct Point {
    /// #     x: i32,
    /// #     y: i32,
    /// #     z: i32,
    /// # }
    /// # let zero_point = Point { x: 0, y: 0, z: 0 };
    /// #
    /// # #[non_exhaustive]
    /// # struct Options {
    /// #     a: bool,
    /// #     b: i32,
    /// # }
    /// # let default_options = Options { a: false, b: 0 };
    /// #
    /// // Bad
    /// Point {
    ///     x: 1,
    ///     y: 1,
    ///     z: 1,
    ///     ..zero_point
    /// };
    ///
    /// // Ok
    /// Point {
    ///     x: 1,
    ///     y: 1,
    ///     ..zero_point
    /// };
    ///
    /// // this lint is not applied to structs marked with [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)
    /// // Ok
    /// Options {
    ///     a: true,
    ///     b: 321,
    ///     ..default_options
    ///  };
    /// ```
    pub NEEDLESS_UPDATE,
    complexity,
    "using `Foo { ..base }` when there are no missing fields"
}

declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]);

impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind {
            let ty = cx.typeck_results().expr_ty(expr);
            if let ty::Adt(def, _) = ty.kind() {
                if fields.len() == def.non_enum_variant().fields.len()
                    && !def.variants[0_usize.into()].is_field_list_non_exhaustive()
                {
                    span_lint(
                        cx,
                        NEEDLESS_UPDATE,
                        base.span,
                        "struct update has no effect, all the fields in the struct have already been specified",
                    );
                }
            }
        }
    }
}
<commit_msg>remove example<commit_after>use crate::utils::span_lint;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks for needlessly including a base struct on update
    /// when all fields are changed anyway.
    ///
    /// This lint is not applied to structs marked with
    /// [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).
    ///
    /// **Why is this bad?** This will cost resources (because the base has to be
    /// somewhere), and make the code less readable.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// # struct Point {
    /// #     x: i32,
    /// #     y: i32,
    /// #     z: i32,
    /// # }
    /// # let zero_point = Point { x: 0, y: 0, z: 0 };
    ///
    /// // Bad
    /// Point {
    ///     x: 1,
    ///     y: 1,
    ///     z: 1,
    ///     ..zero_point
    /// };
    ///
    /// // Ok
    /// Point {
    ///     x: 1,
    ///     y: 1,
    ///     ..zero_point
    /// };
    /// ```
    pub NEEDLESS_UPDATE,
    complexity,
    "using `Foo { ..base }` when there are no missing fields"
}

declare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]);

impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind {
            let ty = cx.typeck_results().expr_ty(expr);
            if let ty::Adt(def, _) = ty.kind() {
                if fields.len() == def.non_enum_variant().fields.len()
                    && !def.variants[0_usize.into()].is_field_list_non_exhaustive()
                {
                    span_lint(
                        cx,
                        NEEDLESS_UPDATE,
                        base.span,
                        "struct update has no effect, all the fields in the struct have already been specified",
                    );
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Rust representations of Github API data structures

use super::{SortDirection, Error, State as StdState};
use super::issues::Sort;
use std::collections::HashMap;
use std::hash::Hash;
use std::option::Option;
use url::form_urlencoded;

extern crate serializable_enum;
extern crate serde;
extern crate serde_json;

include!(concat!(env!("OUT_DIR"), "/rep.rs"));

serializable_enum! {
    /// representation of deployment and commit status states
    #[derive(Clone, Debug, PartialEq)]
    pub enum StatusState {
        /// pending
        Pending,
        /// success
        Success,
        /// error
        Error,
        /// failure
        Failure,
    }
    StatusStateVisitor
}

impl_as_ref_from_str! {
    StatusState {
        Pending => "pending",
        Success => "success",
        Error => "error",
        Failure => "failure",
    }
    Error::Parse
}

impl Default for StatusState {
    fn default() -> StatusState {
        StatusState::Pending
    }
}

#[cfg(test)]
mod tests {
    use super::super::State as StdState;
    use serde::ser::Serialize;
    use std::collections::HashMap;
    use super::*;
    use super::serde_json;

    fn test_encoding<E: Serialize>(tests: Vec<(E, &str)>) {
        for test in tests {
            match test {
                (k, v) => assert_eq!(serde_json::to_string(&k).unwrap(), v),
            }
        }
    }

    #[test]
    fn gist_reqs() {
        let mut files = HashMap::new();
        files.insert("foo", "bar");
        let tests = vec![
            (
                GistOptions::new(None as Option<String>, true, files.clone()),
                r#"{"public":true,"files":{"foo":{"content":"bar"}}}"#
            ),
            (
                GistOptions::new(Some("desc"), true, files.clone()),
                r#"{"description":"desc","public":true,"files":{"foo":{"content":"bar"}}}"#
            )
        ];
        test_encoding(tests);
    }

    #[test]
    fn deserialize_status_state() {
        for (json, expect) in vec![("\"pending\"", StatusState::Pending),
                                   ("\"success\"", StatusState::Success),
                                   ("\"error\"", StatusState::Error),
                                   ("\"failure\"", StatusState::Failure)] {
            assert_eq!(serde_json::from_str::<StatusState>(json).unwrap(), expect)
        }
    }

    #[test]
    fn deployment_reqs() {
        let tests = vec![(DeploymentOptions::builder("test").build(),
                          r#"{"ref":"test"}"#),
                         (DeploymentOptions::builder("test").task("launchit").build(),
                          r#"{"ref":"test","task":"launchit"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn deployment_status_reqs() {
        let tests = vec![
            (
                DeploymentStatusOptions::builder(StatusState::Pending).build(),
                r#"{"state":"pending"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").build(),
                r#"{"state":"pending","target_url":"http://host.com"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").description("desc").build(),
                r#"{"state":"pending","target_url":"http://host.com","description":"desc"}"#
            ),
        ];
        test_encoding(tests)
    }

    #[test]
    fn gist_req() {
        let mut files = HashMap::new();
        files.insert("test", "foo");
        let tests = vec![
            (
                GistOptions::builder(files.clone()).build(),
                r#"{"files":{"test":{"content":"foo"}}}"#
            ),
            (
                GistOptions::builder(files.clone()).description("desc").build(),
                r#"{"description":"desc","files":{"test":{"content":"foo"}}}"#
                    ),
            (
                GistOptions::builder(files.clone()).description("desc").public(false).build(),
                r#"{"description":"desc","public":false,"files":{"test":{"content":"foo"}}}"#
            )
        ];
        test_encoding(tests)
    }

    #[test]
    fn pullreq_edits() {
        let tests = vec![(PullEditOptions::builder().title("test").build(),
                          r#"{"title":"test"}"#),
                         (PullEditOptions::builder().title("test").body("desc").build(),
                          r#"{"title":"test","body":"desc"}"#),
                         (PullEditOptions::builder().state("closed").build(),
                          r#"{"state":"closed"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn status_reqs() {
        let tests = vec![(StatusOptions::builder(StatusState::Pending).build(),
                  r#"{"state":"pending"}"#),
                 (StatusOptions::builder(StatusState::Success)
                      .target_url("http://acme.com")
                      .build(),
                  r#"{"state":"success","target_url":"http://acme.com"}"#),
                 (StatusOptions::builder(StatusState::Error).description("desc").build(),
                  r#"{"state":"error","description":"desc"}"#),
                 (StatusOptions::builder(StatusState::Failure)
                      .target_url("http://acme.com")
                      .description("desc")
                      .build(),
                  r#"{"state":"failure","target_url":"http://acme.com","description":"desc"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, &str)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (
                IssueListOptions::builder().build(),
                "state=open&sort=created&direction=asc"
            ),
            (
                IssueListOptions::builder().state(StdState::Closed).build(),
                "state=closed&sort=created&direction=asc"
             ),
            (
                IssueListOptions::builder().labels(vec!["foo", "bar"]).build(),
                "state=open&sort=created&direction=asc&labels=foo%2Cbar"
            ),
        ];
        test_serialize(tests)
    }
}
<commit_msg>more deployment option tests<commit_after>//! Rust representations of Github API data structures

use super::{SortDirection, Error, State as StdState};
use super::issues::Sort;
use std::collections::HashMap;
use std::hash::Hash;
use std::option::Option;
use url::form_urlencoded;

extern crate serializable_enum;
extern crate serde;
extern crate serde_json;

include!(concat!(env!("OUT_DIR"), "/rep.rs"));

serializable_enum! {
    /// representation of deployment and commit status states
    #[derive(Clone, Debug, PartialEq)]
    pub enum StatusState {
        /// pending
        Pending,
        /// success
        Success,
        /// error
        Error,
        /// failure
        Failure,
    }
    StatusStateVisitor
}

impl_as_ref_from_str! {
    StatusState {
        Pending => "pending",
        Success => "success",
        Error => "error",
        Failure => "failure",
    }
    Error::Parse
}

impl Default for StatusState {
    fn default() -> StatusState {
        StatusState::Pending
    }
}

#[cfg(test)]
mod tests {
    use super::super::State as StdState;
    use serde::ser::Serialize;
    use std::collections::{HashMap, BTreeMap};
    use super::*;
    use super::serde_json;

    fn test_encoding<E: Serialize>(tests: Vec<(E, &str)>) {
        for test in tests {
            match test {
                (k, v) => assert_eq!(serde_json::to_string(&k).unwrap(), v),
            }
        }
    }

    #[test]
    fn gist_reqs() {
        let mut files = HashMap::new();
        files.insert("foo", "bar");
        let tests = vec![
            (
                GistOptions::new(None as Option<String>, true, files.clone()),
                r#"{"public":true,"files":{"foo":{"content":"bar"}}}"#
            ),
            (
                GistOptions::new(Some("desc"), true, files.clone()),
                r#"{"description":"desc","public":true,"files":{"foo":{"content":"bar"}}}"#
            )
        ];
        test_encoding(tests);
    }

    #[test]
    fn deserialize_status_state() {
        for (json, expect) in vec![("\"pending\"", StatusState::Pending),
                                   ("\"success\"", StatusState::Success),
                                   ("\"error\"", StatusState::Error),
                                   ("\"failure\"", StatusState::Failure)] {
            assert_eq!(serde_json::from_str::<StatusState>(json).unwrap(), expect)
        }
    }

    #[test]
    fn deployment_reqs() {
        let mut payload = BTreeMap::new();
        payload.insert("user", "atmos");
        payload.insert("room_id", "123456");
        let tests = vec![
            (
                DeploymentOptions::builder("test").build(),
                r#"{"ref":"test"}"#
            ),
            (
                DeploymentOptions::builder("test").task("launchit").build(),
                r#"{"ref":"test","task":"launchit"}"#
            ),
            (
                DeploymentOptions::builder("topic-branch").description("description").payload(payload).build(),
                r#"{"ref":"topic-branch","payload":"{\"room_id\":\"123456\",\"user\":\"atmos\"}","description":"description"}"#
            )
        ];
        test_encoding(tests)
    }

    #[test]
    fn deployment_status_reqs() {
        let tests = vec![
            (
                DeploymentStatusOptions::builder(StatusState::Pending).build(),
                r#"{"state":"pending"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").build(),
                r#"{"state":"pending","target_url":"http://host.com"}"#
            ),
            (
                DeploymentStatusOptions::builder(StatusState::Pending).target_url("http://host.com").description("desc").build(),
                r#"{"state":"pending","target_url":"http://host.com","description":"desc"}"#
            ),
        ];
        test_encoding(tests)
    }

    #[test]
    fn gist_req() {
        let mut files = HashMap::new();
        files.insert("test", "foo");
        let tests = vec![
            (
                GistOptions::builder(files.clone()).build(),
                r#"{"files":{"test":{"content":"foo"}}}"#
            ),
            (
                GistOptions::builder(files.clone()).description("desc").build(),
                r#"{"description":"desc","files":{"test":{"content":"foo"}}}"#
            ),
            (
                GistOptions::builder(files.clone()).description("desc").public(false).build(),
                r#"{"description":"desc","public":false,"files":{"test":{"content":"foo"}}}"#
            )
        ];
        test_encoding(tests)
    }

    #[test]
    fn pullreq_edits() {
        let tests = vec![(PullEditOptions::builder().title("test").build(),
                          r#"{"title":"test"}"#),
                         (PullEditOptions::builder().title("test").body("desc").build(),
                          r#"{"title":"test","body":"desc"}"#),
                         (PullEditOptions::builder().state("closed").build(),
                          r#"{"state":"closed"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn status_reqs() {
        let tests = vec![(StatusOptions::builder(StatusState::Pending).build(),
                  r#"{"state":"pending"}"#),
                 (StatusOptions::builder(StatusState::Success)
                      .target_url("http://acme.com")
                      .build(),
                  r#"{"state":"success","target_url":"http://acme.com"}"#),
                 (StatusOptions::builder(StatusState::Error).description("desc").build(),
                  r#"{"state":"error","description":"desc"}"#),
                 (StatusOptions::builder(StatusState::Failure)
                      .target_url("http://acme.com")
                      .description("desc")
                      .build(),
                  r#"{"state":"failure","target_url":"http://acme.com","description":"desc"}"#)];
        test_encoding(tests)
    }

    #[test]
    fn list_reqs() {
        fn test_serialize(tests: Vec<(IssueListOptions, &str)>) {
            for test in tests {
                match test {
                    (k, v) => assert_eq!(k.serialize(), v),
                }
            }
        }
        let tests = vec![
            (
                IssueListOptions::builder().build(),
                "state=open&sort=created&direction=asc"
            ),
            (
                IssueListOptions::builder().state(StdState::Closed).build(),
                "state=closed&sort=created&direction=asc"
             ),
            (
                IssueListOptions::builder().labels(vec!["foo", "bar"]).build(),
                "state=open&sort=created&direction=asc&labels=foo%2Cbar"
            ),
        ];
        test_serialize(tests)
    }
}
<|endoftext|>


<commit_before><commit_msg>Clean up syntax<commit_after><|endoftext|>