<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_service;
extern crate uuid;

#[macro_use]
extern crate clap;
extern crate es_proto;

use std::io;
use std::net::SocketAddr;
use std::thread;
use std::process;
use uuid::Uuid;

use futures::{Future, IntoFuture, Stream, Sink};
use futures::future::{BoxFuture, Either};
use tokio_core::reactor::{Core, Handle};
use tokio_service::Service;
use futures::sync::{oneshot, mpsc};

use clap::{Arg, App, SubCommand};

use es_proto::{EventStoreClient, Package, Message, Builder, ExpectedVersion, StreamVersion, UsernamePassword, Direction};

#[derive(Debug)]
enum ReadMode {
    ForwardOnce{ skip: usize, count: usize },
    Backward{ skip: usize, count: usize }
}

impl ReadMode {
    fn into_request(self, stream_id: &str) -> Message {
        use ReadMode::*;
        match self {
            ForwardOnce { skip, count: 1 } | Backward { skip, count: 1 } => {
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_event()
                    .stream_id(stream_id.to_owned())
                    .event_number(ver)
                    .resolve_link_tos(true)
                    .require_master(false)
                    .build_message()
            },
            ForwardOnce { skip, count } => {
                // TODO: perhaps bad choice of option?
                // TODO: handle at main
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_stream_events()
                    .direction(Direction::Forward) // TODO: ReadDirection would be more clear?
                    .stream_id(stream_id.to_owned())
                    .from_event_number(ver)
                    .max_count(count as u8) // TODO: restrict at main
                    .build_message()
            },
            Backward { skip, count } => {
                // last is -1, -1; TODO: cannot fit usize
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_stream_events()
                    .direction(Direction::Forward) // TODO: ReadDirection would be more clear?
                    .stream_id(stream_id.to_owned())
                    .from_event_number(ver)
                    .max_count(count as u8) // TODO: restrict at main
                    .build_message()
            }
        }
    }
}

fn main() {

    let matches = App::new(crate_name!())
        .version(crate_version!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .arg(Arg::with_name("hostname")
                .short("h")
                .long("host")
                .value_name("HOST")
                .takes_value(true)
                .help("The name of the host to connect to, default: 127.0.0.1"))
        .arg(Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("PORT")
                .takes_value(true)
                .help("The port to connect to, default: 1113"))
        .arg(Arg::with_name("verbose")
                 .short("v")
                 .long("verbose")
                 .takes_value(false)
                 .help("Output verbose timings"))
        .subcommand(SubCommand::with_name("ping")
                        .about("Send a ping to the host after possibly authenticating depending on the options"))
        .subcommand(SubCommand::with_name("write")
                        .about("Write single event to a given stream")
                        .arg(Arg::with_name("stream_id")
                                .value_name("STREAM-ID")
                                .required(true)
                                .index(1)
                                .help("Stream id to write to"))
                        .arg(Arg::with_name("expected_version")
                                .value_name("EXPECTED_VERSION")
                                .required(true)
                                .index(2)
                                .help("Acceptable values: any|created|n where n >= -2"))
                        .arg(Arg::with_name("type")
                                .value_name("TYPE")
                                .required(true)
                                .index(3)
                                .help("Type name of the event"))
                        .arg(Arg::with_name("data")
                                .value_name("DATA")
                                .required(true)
                                .index(4)
                                .help("Raw bytes of data."))
                        .arg(Arg::with_name("metadata")
                                .value_name("METADATA")
                                .required(false)
                                .index(5)
                                .help("Raw bytes of metadata, optional"))
                        .arg(Arg::with_name("json")
                                .short("j")
                                .long("json")
                                .takes_value(false)
                                .help("Flags the data and metadata (when given) as json values")))
        .subcommand(SubCommand::with_name("read")
                        .about("Read event(s) of a stream")
                        .arg(Arg::with_name("stream_id")
                                .value_name("STREAM-ID")
                                .required(true)
                                .index(1)
                                .help("Stream id to read from, or $all for every stream"))
                        .arg(Arg::with_name("count")
                             .value_name("N")
                             .short("c")
                             .long("count")
                             .takes_value(true)
                             .help("Number of events to read, 'all' or N > 0, defaults to 1"))
                        .arg(Arg::with_name("skip")
                             .value_name("SKIP")
                             .short("s")
                             .long("skip")
                             .takes_value(true)
                             .help("The event number to start from, defaults to 0"))
                        .arg(Arg::with_name("mode")
                             .value_name("MODE")
                             .short("m")
                             .long("mode")
                             .takes_value(true)
                             .possible_values(&["forward-forever", "forward-once", "backward"])
                             .help("'forward-once' reads up until the current latest,
'forward-forever' stays and awaits for new messages until count has been reached,
'backward' goes to up to first event"))
                        .arg(Arg::with_name("output")
                             .value_name("OUTPUT_MODE")
                             .short("o")
                             .long("output")
                             .takes_value(true)
                             .possible_values(&["debug", "utf8_lossy", "json_oneline", "hex"])
                             .help("'debug' will print the structure with {:?} or {:#?} depending on verbose
'utf8_lossy' will attempt to decode data as utf8
'json_oneline' will parse the json and stringify on one line
'hex' will write data as hexadecimals")))
        .get_matches();

    let addr = {
        let s = format!("{}:{}", matches.value_of("hostname").unwrap_or("127.0.0.1"), matches.value_of("port").unwrap_or("1113"));
        s.parse::<SocketAddr>().expect("Failed to parse host:port as SocketAddr")
    };

    let verbose = matches.is_present("verbose");

    let res = if let Some(matches) = matches.subcommand_matches("ping") {
        ping(addr, verbose)
    } else if let Some(w) = matches.subcommand_matches("write") {
        let mut builder = Builder::write_events();
        builder.stream_id(w.value_of("stream_id").unwrap().to_owned())
            .expected_version(match w.value_of("expected_version").unwrap() {
                "any" => ExpectedVersion::Any,
                "created" => ExpectedVersion::NewStream,
                n => ExpectedVersion::Exact(StreamVersion::from_opt(n.parse().unwrap()).expect("Stream version out of bounds"))
            })
            .require_master(w.is_present("require_master"));

        {
            let mut event = builder.new_event();

            event = event.data(w.value_of("data").unwrap().as_bytes().iter().cloned().collect::<Vec<_>>())
                .data_content_type(w.is_present("json"))
                .event_type(w.value_of("type").unwrap().to_owned());

            event = if let Some(x) = w.value_of("metadata") {
                event.metadata(x.as_bytes().iter().cloned().collect::<Vec<_>>())
                    .metadata_content_type(w.is_present("json"))
            } else {
                event
            };

            event.done();
        }

        write(addr, verbose, builder.build_package(None, None))
    } else if let Some(r) = matches.subcommand_matches("read") {
        let stream_id = r.value_of("stream_id").unwrap();
        let count: usize = match r.value_of("count").unwrap_or("1") {
            "all" => usize::max_value(),
            s => s.parse().expect("Parsing count failed"),
        };

        let skip: usize = r.value_of("skip").unwrap_or("0").parse().expect("Parsing skip failed");
        let mode = match r.value_of("mode") {
            None | Some("forward-once") => ReadMode::ForwardOnce{skip, count},
            Some("forward-forever") => unimplemented!(),
            Some("backward") => ReadMode::Backward{skip, count},
            _ => unreachable!(),
        };

        read(addr, verbose, stream_id, mode)
    } else {
        println!("Subcommand is required.\n\n{}", matches.usage());
        process::exit(1);
    };

    if let Err(e) = res {
        println!("Failure: {:?}", e);
        process::exit(1);
    }
}

use std::time::Instant;

fn ping(addr: SocketAddr, verbose: bool) -> Result<(), io::Error> {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let started = Instant::now();

    let job = EventStoreClient::connect(&addr, &handle)
        .map(|client| (client, Instant::now()))
        .and_then(|(client, connected)| {

            let f = client.call(Builder::ping().build_package(None, None));
            let send_began = Instant::now();

            f.map(move |resp| (resp, connected, send_began))
        }).and_then(|(pong, connected, send_began)| {
            let received = Instant::now();
            match pong.message {
                Message::Pong => Ok((connected, send_began, received)),
                msg => Err(io::Error::new(io::ErrorKind::Other, format!("Unexpected response: {:?}", msg)))
            }
        }).and_then(move |(connected, send_began, received)| {
            if verbose {
                print_elapsed("connected in  ", connected - started);
                print_elapsed("ready to send ", send_began - connected);
                print_elapsed("received in   ", received - send_began);
                print_elapsed("total         ", started.elapsed());
            } else {
                print_elapsed("pong received in", started.elapsed());
            }

            Ok(())
        });

    core.run(job)
}

fn write(addr: SocketAddr, verbose: bool, pkg: Package) -> Result<(), io::Error> {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let client = EventStoreClient::connect(&addr, &handle);
    let started = Instant::now();

    let job = client.and_then(|client| {
        client.call(pkg)
    }).and_then(|resp| {
        match resp.message {
            Message::WriteEventsCompleted(Ok(success)) => {
                print_elapsed("Success in", started.elapsed());
                if verbose {
                    println!("{:#?}", success);
                }
                Ok(())
            },
            Message::WriteEventsCompleted(Err(reason)) => {
                Err(io::Error::new(io::ErrorKind::Other, format!("{}", reason)))
            },
            x => {
                Err(io::Error::new(io::ErrorKind::Other, format!("Unexpected response: {:?}", x)))
            }
        }
    });

    core.run(job)
}

fn read(addr: SocketAddr, verbose: bool, stream_id: &str, mode: ReadMode) -> Result<(), io::Error> {
    /*if stream_id == "$all" {
        unimplemented!();
    }*/

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let client = EventStoreClient::connect(&addr, &handle);
    let started = Instant::now();

    let job = client.and_then(|client| {
        client.call(Package {
            authentication: None,
            correlation_id: Uuid::new_v4(),
            message: mode.into_request(stream_id),
        })
    }).and_then(|resp| {
        println!("{:#?}", resp);
        Ok(())
    });

    core.run(job)
}

use std::time::Duration;

fn print_elapsed(subject: &str, d: Duration) {
    println!("{} {}.{:06}ms", subject, d.as_secs() * 1000 + d.subsec_nanos() as u64 / 1_000_000, d.subsec_nanos() % 1_000_000);
}

/*
fn nice(addr: &SocketAddr, handle: &Handle) {
    let client = EventStoreClient::connect(&addr, &handle);
    client.and_then(|client| {

    });
}*/

/*
struct Client {
    tx: mpsc::Sender<(Package, oneshot::Sender<Result<Package, io::Error>>)>,
}

impl Client {
    fn new(addr: &SocketAddr, handle: &Handle) -> Client {
        let (tx, rx) = mpsc::channel::<(Package, oneshot::Sender<Result<Package, io::Error>>)>(4);
        let client = EventStoreClient::connect(addr, handle);
        let task = client.and_then(move |client| {
            rx.for_each(move |(pkg, tx)| {
                client.call(pkg).then(|res| {
                    let ret = match res {
                        Ok(_) => Ok(()),
                        Err(_) => Err(())
                    };
                    tx.complete(res);
                    ret
                })
            }).map_err(|_| io::Error::new(io::ErrorKind::Other, "dunno?"))
        });
        handle.spawn(task.then(|res| match res { Ok(_) => Ok(()), Err(_) => Err(()) }));
        Client { tx: tx }
    }

    fn call(&self, msg: Message) -> MessageFuture {
        let (tx, rx) = oneshot::channel();

        self.tx.send(());
    }
}*/

// connecting
// ready
// heartbeat
// disconnected
<commit_msg>testclient: cleanup<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_service;
extern crate uuid;

#[macro_use]
extern crate clap;
extern crate es_proto;

use std::io;
use std::net::SocketAddr;
use std::process;
use uuid::Uuid;

use futures::Future;
use tokio_core::reactor::Core;
use tokio_service::Service;

use clap::{Arg, App, SubCommand};

use es_proto::{EventStoreClient, Package, Message, Builder, ExpectedVersion, StreamVersion, Direction};

#[derive(Debug)]
enum ReadMode {
    ForwardOnce{ skip: usize, count: usize },
    Backward{ skip: usize, count: usize }
}

impl ReadMode {
    fn into_request(self, stream_id: &str) -> Message {
        use ReadMode::*;
        match self {
            ForwardOnce { skip, count: 1 } | Backward { skip, count: 1 } => {
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_event()
                    .stream_id(stream_id.to_owned())
                    .event_number(ver)
                    .resolve_link_tos(true)
                    .require_master(false)
                    .build_message()
            },
            ForwardOnce { skip, count } => {
                // TODO: perhaps bad choice of option?
                // TODO: handle at main
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_stream_events()
                    .direction(Direction::Forward) // TODO: ReadDirection would be more clear?
                    .stream_id(stream_id.to_owned())
                    .from_event_number(ver)
                    .max_count(count as u8) // TODO: restrict at main
                    .build_message()
            },
            Backward { skip, count } => {
                // last is -1, -1; TODO: cannot fit usize
                let ver = StreamVersion::from_opt(skip as u32).expect("Stream version overflow");
                Builder::read_stream_events()
                    .direction(Direction::Forward) // TODO: ReadDirection would be more clear?
                    .stream_id(stream_id.to_owned())
                    .from_event_number(ver)
                    .max_count(count as u8) // TODO: restrict at main
                    .build_message()
            }
        }
    }
}

fn main() {

    let matches = App::new(crate_name!())
        .version(crate_version!())
        .about(crate_description!())
        .author(crate_authors!("\n"))
        .arg(Arg::with_name("hostname")
                .short("h")
                .long("host")
                .value_name("HOST")
                .takes_value(true)
                .help("The name of the host to connect to, default: 127.0.0.1"))
        .arg(Arg::with_name("port")
                .short("p")
                .long("port")
                .value_name("PORT")
                .takes_value(true)
                .help("The port to connect to, default: 1113"))
        .arg(Arg::with_name("verbose")
                 .short("v")
                 .long("verbose")
                 .takes_value(false)
                 .help("Output verbose timings"))
        .subcommand(SubCommand::with_name("ping")
                        .about("Send a ping to the host after possibly authenticating depending on the options"))
        .subcommand(SubCommand::with_name("write")
                        .about("Write single event to a given stream")
                        .arg(Arg::with_name("stream_id")
                                .value_name("STREAM-ID")
                                .required(true)
                                .index(1)
                                .help("Stream id to write to"))
                        .arg(Arg::with_name("expected_version")
                                .value_name("EXPECTED_VERSION")
                                .required(true)
                                .index(2)
                                .help("Acceptable values: any|created|n where n >= -2"))
                        .arg(Arg::with_name("type")
                                .value_name("TYPE")
                                .required(true)
                                .index(3)
                                .help("Type name of the event"))
                        .arg(Arg::with_name("data")
                                .value_name("DATA")
                                .required(true)
                                .index(4)
                                .help("Raw bytes of data."))
                        .arg(Arg::with_name("metadata")
                                .value_name("METADATA")
                                .required(false)
                                .index(5)
                                .help("Raw bytes of metadata, optional"))
                        .arg(Arg::with_name("json")
                                .short("j")
                                .long("json")
                                .takes_value(false)
                                .help("Flags the data and metadata (when given) as json values")))
        .subcommand(SubCommand::with_name("read")
                        .about("Read event(s) of a stream")
                        .arg(Arg::with_name("stream_id")
                                .value_name("STREAM-ID")
                                .required(true)
                                .index(1)
                                .help("Stream id to read from, or $all for every stream"))
                        .arg(Arg::with_name("count")
                             .value_name("N")
                             .short("c")
                             .long("count")
                             .takes_value(true)
                             .help("Number of events to read, 'all' or N > 0, defaults to 1"))
                        .arg(Arg::with_name("skip")
                             .value_name("SKIP")
                             .short("s")
                             .long("skip")
                             .takes_value(true)
                             .help("The event number to start from, defaults to 0"))
                        .arg(Arg::with_name("mode")
                             .value_name("MODE")
                             .short("m")
                             .long("mode")
                             .takes_value(true)
                             .possible_values(&["forward-forever", "forward-once", "backward"])
                             .help("'forward-once' reads up until the current latest,
'forward-forever' stays and awaits for new messages until count has been reached,
'backward' goes to up to first event"))
                        .arg(Arg::with_name("output")
                             .value_name("OUTPUT_MODE")
                             .short("o")
                             .long("output")
                             .takes_value(true)
                             .possible_values(&["debug", "utf8_lossy", "json_oneline", "hex"])
                             .help("'debug' will print the structure with {:?} or {:#?} depending on verbose
'utf8_lossy' will attempt to decode data as utf8
'json_oneline' will parse the json and stringify on one line
'hex' will write data as hexadecimals")))
        .get_matches();

    let addr = {
        let s = format!("{}:{}", matches.value_of("hostname").unwrap_or("127.0.0.1"), matches.value_of("port").unwrap_or("1113"));
        s.parse::<SocketAddr>().expect("Failed to parse host:port as SocketAddr")
    };

    let verbose = matches.is_present("verbose");

    let res = if let Some(_) = matches.subcommand_matches("ping") {
        ping(addr, verbose)
    } else if let Some(w) = matches.subcommand_matches("write") {
        let mut builder = Builder::write_events();
        builder.stream_id(w.value_of("stream_id").unwrap().to_owned())
            .expected_version(match w.value_of("expected_version").unwrap() {
                "any" => ExpectedVersion::Any,
                "created" => ExpectedVersion::NewStream,
                n => ExpectedVersion::Exact(StreamVersion::from_opt(n.parse().unwrap()).expect("Stream version out of bounds"))
            })
            .require_master(w.is_present("require_master"));

        {
            let mut event = builder.new_event();

            event = event.data(w.value_of("data").unwrap().as_bytes().iter().cloned().collect::<Vec<_>>())
                .data_content_type(w.is_present("json"))
                .event_type(w.value_of("type").unwrap().to_owned());

            event = if let Some(x) = w.value_of("metadata") {
                event.metadata(x.as_bytes().iter().cloned().collect::<Vec<_>>())
                    .metadata_content_type(w.is_present("json"))
            } else {
                event
            };

            event.done();
        }

        write(addr, verbose, builder.build_package(None, None))
    } else if let Some(r) = matches.subcommand_matches("read") {
        let stream_id = r.value_of("stream_id").unwrap();
        let count: usize = match r.value_of("count").unwrap_or("1") {
            "all" => usize::max_value(),
            s => s.parse().expect("Parsing count failed"),
        };

        let skip: usize = r.value_of("skip").unwrap_or("0").parse().expect("Parsing skip failed");
        let mode = match r.value_of("mode") {
            None | Some("forward-once") => ReadMode::ForwardOnce{skip, count},
            Some("forward-forever") => unimplemented!(),
            Some("backward") => ReadMode::Backward{skip, count},
            _ => unreachable!(),
        };

        read(addr, verbose, stream_id, mode)
    } else {
        println!("Subcommand is required.\n\n{}", matches.usage());
        process::exit(1);
    };

    if let Err(e) = res {
        println!("Failure: {:?}", e);
        process::exit(1);
    }
}

use std::time::Instant;

fn ping(addr: SocketAddr, verbose: bool) -> Result<(), io::Error> {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let started = Instant::now();

    let job = EventStoreClient::connect(&addr, &handle)
        .map(|client| (client, Instant::now()))
        .and_then(|(client, connected)| {

            let f = client.call(Builder::ping().build_package(None, None));
            let send_began = Instant::now();

            f.map(move |resp| (resp, connected, send_began))
        }).and_then(|(pong, connected, send_began)| {
            let received = Instant::now();
            match pong.message {
                Message::Pong => Ok((connected, send_began, received)),
                msg => Err(io::Error::new(io::ErrorKind::Other, format!("Unexpected response: {:?}", msg)))
            }
        }).and_then(move |(connected, send_began, received)| {
            if verbose {
                print_elapsed("connected in  ", connected - started);
                print_elapsed("ready to send ", send_began - connected);
                print_elapsed("received in   ", received - send_began);
                print_elapsed("total         ", started.elapsed());
            } else {
                print_elapsed("pong received in", started.elapsed());
            }

            Ok(())
        });

    core.run(job)
}

fn write(addr: SocketAddr, verbose: bool, pkg: Package) -> Result<(), io::Error> {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let client = EventStoreClient::connect(&addr, &handle);
    let started = Instant::now();

    let job = client.and_then(|client| {
        client.call(pkg)
    }).and_then(|resp| {
        match resp.message {
            Message::WriteEventsCompleted(Ok(success)) => {
                print_elapsed("Success in", started.elapsed());
                if verbose {
                    println!("{:#?}", success);
                }
                Ok(())
            },
            Message::WriteEventsCompleted(Err(reason)) => {
                Err(io::Error::new(io::ErrorKind::Other, format!("{}", reason)))
            },
            x => {
                Err(io::Error::new(io::ErrorKind::Other, format!("Unexpected response: {:?}", x)))
            }
        }
    });

    core.run(job)
}

fn read(addr: SocketAddr, _: bool, stream_id: &str, mode: ReadMode) -> Result<(), io::Error> {
    /*if stream_id == "$all" {
        unimplemented!();
    }*/

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let client = EventStoreClient::connect(&addr, &handle);

    let job = client.and_then(|client| {
        client.call(Package {
            authentication: None,
            correlation_id: Uuid::new_v4(),
            message: mode.into_request(stream_id),
        })
    }).and_then(|resp| {
        println!("{:#?}", resp);
        Ok(())
    });

    core.run(job)
}

use std::time::Duration;

fn print_elapsed(subject: &str, d: Duration) {
    println!("{} {}.{:06}ms", subject, d.as_secs() * 1000 + d.subsec_nanos() as u64 / 1_000_000, d.subsec_nanos() % 1_000_000);
}

/*
fn nice(addr: &SocketAddr, handle: &Handle) {
    let client = EventStoreClient::connect(&addr, &handle);
    client.and_then(|client| {

    });
}*/

/*
struct Client {
    tx: mpsc::Sender<(Package, oneshot::Sender<Result<Package, io::Error>>)>,
}

impl Client {
    fn new(addr: &SocketAddr, handle: &Handle) -> Client {
        let (tx, rx) = mpsc::channel::<(Package, oneshot::Sender<Result<Package, io::Error>>)>(4);
        let client = EventStoreClient::connect(addr, handle);
        let task = client.and_then(move |client| {
            rx.for_each(move |(pkg, tx)| {
                client.call(pkg).then(|res| {
                    let ret = match res {
                        Ok(_) => Ok(()),
                        Err(_) => Err(())
                    };
                    tx.complete(res);
                    ret
                })
            }).map_err(|_| io::Error::new(io::ErrorKind::Other, "dunno?"))
        });
        handle.spawn(task.then(|res| match res { Ok(_) => Ok(()), Err(_) => Err(()) }));
        Client { tx: tx }
    }

    fn call(&self, msg: Message) -> MessageFuture {
        let (tx, rx) = oneshot::channel();

        self.tx.send(());
    }
}*/

// connecting
// ready
// heartbeat
// disconnected
<|endoftext|>


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

use crate::conversion::ToPyObject;
use crate::err::{self, PyErr, PyResult};
use crate::ffi;
use crate::objects::{PyObject, PyInt, PyLong, PyFloat};
use crate::python::{Python, PythonObject, ToPythonPointer};

use super::ObjectProtocol;

/// Operations on numeric objects
pub trait NumberProtocol: ObjectProtocol {
    /// Perform addition (self + other)
    ///
    /// Invokes the `__add__` magic-method
    #[inline]
    fn add(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Add(self.as_ptr(), other))
        })
    }
    /// Perform subtraction (self - other)
    ///
    /// Invokes the `__sub__` magic-method
    #[inline]
    fn subtract(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Subtract(self.as_ptr(), other))
        })
    }
    /// Perform multiplication (self * other)
    ///
    /// Invokes the `__mul__` magic-method
    #[inline]
    fn multiply(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Multiply(self.as_ptr(), other))
        })
    }
    /// Perform matrix multiplication, equivalent to the Python expression `self @ other`
    ///
    /// Invokes the `__matmul__` magic-method
    ///
    /// This method is only available with Python 3.
    ///
    /// See [PEP 0456](https://www.python.org/dev/peps/pep-0465/) for details.
    #[inline]
    #[cfg(feature = "python3-sys")]
    fn matrix_multiply(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_MatrixMultiply(self.as_ptr(), other))
        })
    }
    /// Perform exponentiation, equivalent to the Python expression `self ** other`,
    /// or the two-argument form of the builtin method pow: `pow(self, other)`
    ///
    /// Invokes the `__pow__` magic-method
    ///
    /// See also [NumberProtocol::power_modulo].
    #[inline]
    fn power(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        self.power_modulo(py, other, py.None())
    }
    /// Perform exponentiation modulo an integer,
    /// mathematically equivalent to `self ** other % mod`
    /// but computed much more efficiently.
    ///
    /// Equivalent to invoking the three-argument form
    /// of the builtin `pow` method: `pow(self, other, z)`
    ///
    /// Invoking with a `None` for modulo is equivalent to
    /// the regular power operation.
    ///
    /// Invokes the `__pow__` magic-method
    #[inline]
    fn power_modulo(&self, py: Python, exp: impl ToPyObject, z: impl ToPyObject) -> PyResult<PyObject> {
        exp.with_borrowed_ptr(py, |exp| {
            z.with_borrowed_ptr(py, |z| unsafe {
                err::result_from_owned_ptr(py, ffi::PyNumber_Power(self.as_ptr(), exp, z))
            })
        })
    }
    /// Perform the "true division" operation,
    /// equivalent to the Python expression `self / other`,
    ///
    /// Invokes the `__truediv__` magic-method.
    #[inline]
    fn true_divide(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_TrueDivide(self.as_ptr(), other))
        })
    }
    /// Perform the "floor division" operation,
    /// equivalent to the Python expression `self // other`,
    ///
    /// This method was added in Python 3.
    /// If compiling against Python 2, it unconditional throws an error.
    ///
    /// Invokes the `__floordiv__` magic-method.
    #[inline]
    fn floor_divide(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_FloorDivide(self.as_ptr(), other))
        })
    }
    /// Return the remainder of dividing `self` by `other`,
    /// equivalent to the Python expression `self % other`
    ///
    /// Invokes the `__mod__` magic-method.
    #[inline]
    fn modulo(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Remainder(self.as_ptr(), other))
        })
    }
    /// Perform combined division and modulo,
    /// equivalent to the builtin method `divmod(self, other)`
    ///
    /// Invokes the `__divmod__` magic-method.
    #[inline]
    fn div_mod(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Divmod(self.as_ptr(), other))
        })
    }
    /// Perform the negation of self (-self)
    ///
    /// Invokes the `__neg__` magic-method.
    #[inline]
    fn negative(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Negative(self.as_ptr()))
        }
    }
    /// Invoke the 'positive' operation, equivalent to the
    /// Python expression `+self`
    ///
    /// Invokes the `__pos__` magic-method
    #[inline]
    fn positive(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Positive(self.as_ptr()))
        }
    }
    /// Return the absolute value of self,
    /// equivalent to calling the builtin function `abs`
    ///
    /// Invokes the `__abs__` magic-method.
    #[inline]
    fn absolute(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Absolute(self.as_ptr()))
        }
    }
    /// Perform the bitwise negation of self,
    /// equivalent to the Python expression `~self`
    ///
    /// Invokes the `__invert__` magic-method
    #[inline]
    fn bitwise_invert(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Invert(self.as_ptr()))
        }
    }
    /// Shift this value to the left by the specified number of bits,
    /// equivalent to the Python expression `self << bits`
    ///
    /// Invokes the `__lshift__` magic-method
    #[inline]
    fn left_shift(&self, py: Python, bits: impl ToPyObject) -> PyResult<PyObject> {
        bits.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Lshift(self.as_ptr(), other))
        })
    }
    /// Shift this value to the right by the specified number of bits,
    /// equivalent to the Python expression `self >> bits`
    ///
    /// Invokes the `__rshift__` magic-method
    #[inline]
    fn right_shift(&self, py: Python, bits: impl ToPyObject) -> PyResult<PyObject> {
        bits.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Rshift(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise and" of `self & other`
    ///
    /// Invokes the `__and__` magic-method.
    #[inline]
    fn bitwise_and(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_And(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise exclusive or",
    /// equivalent to Python expression `self ^ other`
    ///
    /// Invokes the `__xor__` magic-method.
    #[inline]
    fn bitwise_xor(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Xor(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise or" of `self | other`
    ///
    /// Invokes the `__or__` magic-method.
    #[inline]
    fn bitwise_or(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Or(self.as_ptr(), other))
        })
    }
    /// Convert this object to an integer,
    /// equivalent to the builtin function `int(self)`
    ///
    /// Invokes the `__int__` magic-method.
    ///
    /// Throws an exception if unable to perform
    /// the conversion.
    #[inline]
    fn as_int(&self, py: Python) -> PyResult<PyLong> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Long(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyLong>(py)?)
    }
    /// Convert this object to a float,
    /// equivalent to the builtin function `float(self)`
    ///
    /// Invokes the `__float__` magic-method.
    ///
    /// Throws an exception if unable to perform
    /// the conversion.
    #[inline]
    fn as_float(&self, py: Python) -> PyResult<PyFloat> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Float(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyFloat>(py)?)
    }
    /// Losslessly convert this object to an integer index,
    /// as if calling `operator.index()`
    ///
    /// The presence of this method indicates
    /// this object is an integer type.
    ///
    /// Calls the `__index__` magic-method.
    ///
    /// See also: [Documentation on the corresponding magic-method](https://docs.python.org/3/reference/datamodel.html?highlight=__index__#object.__index__)
    #[inline]
    fn as_int_index(&self, py: Python) -> PyResult<PyLong> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Index(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyLong>(py)?)
    }
}

impl NumberProtocol for PyObject {}

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

    #[test]
    fn addition() {
        let guard = Python::acquire_gil();
        let py = guard.python();
        let i1 = (5i32).to_py_object(py).into_object();
        let i2 = (12i32).to_py_object(py).into_object();
        let actual_res = i1.add(py, i2).unwrap();
        let expected_res = (17i32).to_py_object(py).into_object();
        assert_eq!(
            actual_res.compare(py, expected_res).unwrap(),
            Ordering::Equal
        );
    }
}
<commit_msg>Rename `as_X` -> `to_X` in new `NumberProtocol` trait.<commit_after>use std::cmp::Ordering;
use std::fmt;

use crate::conversion::ToPyObject;
use crate::err::{self, PyErr, PyResult};
use crate::ffi;
use crate::objects::{PyObject, PyInt, PyLong, PyFloat};
use crate::python::{Python, PythonObject, ToPythonPointer};

use super::ObjectProtocol;

/// Operations on numeric objects
pub trait NumberProtocol: ObjectProtocol {
    /// Perform addition (self + other)
    ///
    /// Invokes the `__add__` magic-method
    #[inline]
    fn add(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Add(self.as_ptr(), other))
        })
    }
    /// Perform subtraction (self - other)
    ///
    /// Invokes the `__sub__` magic-method
    #[inline]
    fn subtract(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Subtract(self.as_ptr(), other))
        })
    }
    /// Perform multiplication (self * other)
    ///
    /// Invokes the `__mul__` magic-method
    #[inline]
    fn multiply(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Multiply(self.as_ptr(), other))
        })
    }
    /// Perform matrix multiplication, equivalent to the Python expression `self @ other`
    ///
    /// Invokes the `__matmul__` magic-method
    ///
    /// This method is only available with Python 3.
    ///
    /// See [PEP 0456](https://www.python.org/dev/peps/pep-0465/) for details.
    #[inline]
    #[cfg(feature = "python3-sys")]
    fn matrix_multiply(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_MatrixMultiply(self.as_ptr(), other))
        })
    }
    /// Perform exponentiation, equivalent to the Python expression `self ** other`,
    /// or the two-argument form of the builtin method pow: `pow(self, other)`
    ///
    /// Invokes the `__pow__` magic-method
    ///
    /// See also [NumberProtocol::power_modulo].
    #[inline]
    fn power(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        self.power_modulo(py, other, py.None())
    }
    /// Perform exponentiation modulo an integer,
    /// mathematically equivalent to `self ** other % mod`
    /// but computed much more efficiently.
    ///
    /// Equivalent to invoking the three-argument form
    /// of the builtin `pow` method: `pow(self, other, z)`
    ///
    /// Invoking with a `None` for modulo is equivalent to
    /// the regular power operation.
    ///
    /// Invokes the `__pow__` magic-method
    #[inline]
    fn power_modulo(&self, py: Python, exp: impl ToPyObject, z: impl ToPyObject) -> PyResult<PyObject> {
        exp.with_borrowed_ptr(py, |exp| {
            z.with_borrowed_ptr(py, |z| unsafe {
                err::result_from_owned_ptr(py, ffi::PyNumber_Power(self.as_ptr(), exp, z))
            })
        })
    }
    /// Perform the "true division" operation,
    /// equivalent to the Python expression `self / other`,
    ///
    /// Invokes the `__truediv__` magic-method.
    #[inline]
    fn true_divide(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_TrueDivide(self.as_ptr(), other))
        })
    }
    /// Perform the "floor division" operation,
    /// equivalent to the Python expression `self // other`,
    ///
    /// This method was added in Python 3.
    /// If compiling against Python 2, it unconditional throws an error.
    ///
    /// Invokes the `__floordiv__` magic-method.
    #[inline]
    fn floor_divide(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_FloorDivide(self.as_ptr(), other))
        })
    }
    /// Return the remainder of dividing `self` by `other`,
    /// equivalent to the Python expression `self % other`
    ///
    /// Invokes the `__mod__` magic-method.
    #[inline]
    fn modulo(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Remainder(self.as_ptr(), other))
        })
    }
    /// Perform combined division and modulo,
    /// equivalent to the builtin method `divmod(self, other)`
    ///
    /// Invokes the `__divmod__` magic-method.
    #[inline]
    fn div_mod(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Divmod(self.as_ptr(), other))
        })
    }
    /// Perform the negation of self (-self)
    ///
    /// Invokes the `__neg__` magic-method.
    #[inline]
    fn negative(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Negative(self.as_ptr()))
        }
    }
    /// Invoke the 'positive' operation, equivalent to the
    /// Python expression `+self`
    ///
    /// Invokes the `__pos__` magic-method
    #[inline]
    fn positive(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Positive(self.as_ptr()))
        }
    }
    /// Return the absolute value of self,
    /// equivalent to calling the builtin function `abs`
    ///
    /// Invokes the `__abs__` magic-method.
    #[inline]
    fn absolute(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Absolute(self.as_ptr()))
        }
    }
    /// Perform the bitwise negation of self,
    /// equivalent to the Python expression `~self`
    ///
    /// Invokes the `__invert__` magic-method
    #[inline]
    fn bitwise_invert(&self, py: Python) -> PyResult<PyObject> {
        unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Invert(self.as_ptr()))
        }
    }
    /// Shift this value to the left by the specified number of bits,
    /// equivalent to the Python expression `self << bits`
    ///
    /// Invokes the `__lshift__` magic-method
    #[inline]
    fn left_shift(&self, py: Python, bits: impl ToPyObject) -> PyResult<PyObject> {
        bits.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Lshift(self.as_ptr(), other))
        })
    }
    /// Shift this value to the right by the specified number of bits,
    /// equivalent to the Python expression `self >> bits`
    ///
    /// Invokes the `__rshift__` magic-method
    #[inline]
    fn right_shift(&self, py: Python, bits: impl ToPyObject) -> PyResult<PyObject> {
        bits.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Rshift(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise and" of `self & other`
    ///
    /// Invokes the `__and__` magic-method.
    #[inline]
    fn bitwise_and(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_And(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise exclusive or",
    /// equivalent to Python expression `self ^ other`
    ///
    /// Invokes the `__xor__` magic-method.
    #[inline]
    fn bitwise_xor(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Xor(self.as_ptr(), other))
        })
    }
    /// Perform the "bitwise or" of `self | other`
    ///
    /// Invokes the `__or__` magic-method.
    #[inline]
    fn bitwise_or(&self, py: Python, other: impl ToPyObject) -> PyResult<PyObject> {
        other.with_borrowed_ptr(py, |other| unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Or(self.as_ptr(), other))
        })
    }
    /// Convert this object to an integer,
    /// equivalent to the builtin function `int(self)`
    ///
    /// Invokes the `__int__` magic-method.
    ///
    /// Throws an exception if unable to perform
    /// the conversion.
    #[inline]
    fn to_int(&self, py: Python) -> PyResult<PyLong> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Long(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyLong>(py)?)
    }
    /// Convert this object to a float,
    /// equivalent to the builtin function `float(self)`
    ///
    /// Invokes the `__float__` magic-method.
    ///
    /// Throws an exception if unable to perform
    /// the conversion.
    #[inline]
    fn to_float(&self, py: Python) -> PyResult<PyFloat> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Float(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyFloat>(py)?)
    }
    /// Losslessly convert this object to an integer index,
    /// as if calling `operator.index()`
    ///
    /// The presence of this method indicates
    /// this object is an integer type.
    ///
    /// Calls the `__index__` magic-method.
    ///
    /// See also: [Documentation on the corresponding magic-method](https://docs.python.org/3/reference/datamodel.html?highlight=__index__#object.__index__)
    #[inline]
    fn to_index(&self, py: Python) -> PyResult<PyLong> {
        let obj = unsafe {
            err::result_from_owned_ptr(py, ffi::PyNumber_Index(self.as_ptr()))?
        };
        Ok(obj.cast_into::<PyLong>(py)?)
    }
}

impl NumberProtocol for PyObject {}

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

    #[test]
    fn addition() {
        let guard = Python::acquire_gil();
        let py = guard.python();
        let i1 = (5i32).to_py_object(py).into_object();
        let i2 = (12i32).to_py_object(py).into_object();
        let actual_res = i1.add(py, i2).unwrap();
        let expected_res = (17i32).to_py_object(py).into_object();
        assert_eq!(
            actual_res.compare(py, expected_res).unwrap(),
            Ordering::Equal
        );
    }
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]

use libc::FILE;
use pyffi::*;
use super::types::*;

#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum NPY_CLIPMODE {
    NPY_CLIP = 0,
    NPY_WRAP = 1,
    NPY_RAISE = 2,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct _object {
    pub ob_refcnt: Py_ssize_t,
    pub ob_type: *mut PyTypeObject,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArrayFlagsObject {
    pub ob_base: PyObject,
    pub arr: *mut PyObject,
    pub flags: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArray_Dims {
    pub ptr: *mut npy_intp,
    pub len: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArray_Chunk {
    pub ob_base: PyObject,
    pub base: *mut PyObject,
    pub ptr: *mut ::std::os::raw::c_void,
    pub len: npy_intp,
    pub flags: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArrayInterface {
    pub two: ::std::os::raw::c_int,
    pub nd: ::std::os::raw::c_int,
    pub typekind: ::std::os::raw::c_char,
    pub itemsize: ::std::os::raw::c_int,
    pub flags: ::std::os::raw::c_int,
    pub shape: *mut npy_intp,
    pub strides: *mut npy_intp,
    pub data: *mut ::std::os::raw::c_void,
    pub descr: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArray_Descr {
    pub ob_base: PyObject,
    pub typeobj: *mut PyTypeObject,
    pub kind: ::std::os::raw::c_char,
    pub type_: ::std::os::raw::c_char,
    pub byteorder: ::std::os::raw::c_char,
    pub flags: ::std::os::raw::c_char,
    pub type_num: ::std::os::raw::c_int,
    pub elsize: ::std::os::raw::c_int,
    pub alignment: ::std::os::raw::c_int,
    pub subarray: *mut _PyArray_Descr__arr_descr,
    pub fields: *mut PyObject,
    pub names: *mut PyObject,
    pub f: *mut PyArray_ArrFuncs,
    pub metadata: *mut PyObject,
    pub c_metadata: *mut NpyAuxData,
    pub hash: npy_hash_t,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArrayObject {
    pub ob_base: PyObject,
    pub data: *mut ::std::os::raw::c_char,
    pub nd: ::std::os::raw::c_int,
    pub dimensions: *mut npy_intp,
    pub strides: *mut npy_intp,
    pub base: *mut PyObject,
    pub descr: *mut PyArray_Descr,
    pub flags: ::std::os::raw::c_int,
    pub weakreflist: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct _PyArray_Descr__arr_descr {
    pub base: *mut PyArray_Descr,
    pub shape: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArray_ArrFuncs {
    pub cast: [PyArray_VectorUnaryFunc; 21usize],
    pub getitem: PyArray_GetItemFunc,
    pub setitem: PyArray_SetItemFunc,
    pub copyswapn: PyArray_CopySwapNFunc,
    pub copyswap: PyArray_CopySwapFunc,
    pub compare: PyArray_CompareFunc,
    pub argmax: PyArray_ArgFunc,
    pub dotfunc: PyArray_DotFunc,
    pub scanfunc: PyArray_ScanFunc,
    pub fromstr: PyArray_FromStrFunc,
    pub nonzero: PyArray_NonzeroFunc,
    pub fill: PyArray_FillFunc,
    pub fillwithscalar: PyArray_FillWithScalarFunc,
    pub sort: [PyArray_SortFunc; 3usize],
    pub argsort: [PyArray_ArgSortFunc; 3usize],
    pub castdict: *mut PyObject,
    pub scalarkind: PyArray_ScalarKindFunc,
    pub cancastscalarkindto: *mut *mut ::std::os::raw::c_int,
    pub cancastto: *mut ::std::os::raw::c_int,
    pub fastclip: PyArray_FastClipFunc,
    pub fastputmask: PyArray_FastPutmaskFunc,
    pub fasttake: PyArray_FastTakeFunc,
    pub argmin: PyArray_ArgFunc,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct NpyAuxData {
    pub free: NpyAuxData_FreeFunc,
    pub clone: NpyAuxData_CloneFunc,
    pub reserved: [*mut ::std::os::raw::c_void; 2usize],
}

pub type PyArray_GetItemFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void)
                                                 -> *mut _object>;
pub type PyArray_SetItemFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut PyObject,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_CopySwapNFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: npy_intp,
                                                 arg5: npy_intp,
                                                 arg6: ::std::os::raw::c_int,
                                                 arg7: *mut ::std::os::raw::c_void)>;
pub type PyArray_CopySwapFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: ::std::os::raw::c_int,
                                                 arg4: *mut ::std::os::raw::c_void)>;
pub type PyArray_NonzeroFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_uchar>;
pub type PyArray_CompareFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *const ::std::os::raw::c_void,
                                                 arg2: *const ::std::os::raw::c_void,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_DotFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: npy_intp,
                                                 arg5: *mut ::std::os::raw::c_void,
                                                 arg6: npy_intp,
                                                 arg7: *mut ::std::os::raw::c_void)>;
pub type PyArray_VectorUnaryFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void,
                                                 arg5: *mut ::std::os::raw::c_void)>;
pub type PyArray_ScanFunc =
    ::std::option::Option<unsafe extern "C" fn(fp: *mut FILE,
                                                 dptr: *mut ::std::os::raw::c_void,
                                                 ignore: *mut ::std::os::raw::c_char,
                                                 arg1: *mut PyArray_Descr)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FromStrFunc =
    ::std::option::Option<unsafe extern "C" fn(s: *mut ::std::os::raw::c_char,
                                                 dptr: *mut ::std::os::raw::c_void,
                                                 endptr: *mut *mut ::std::os::raw::c_char,
                                                 arg1: *mut PyArray_Descr)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FillFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_SortFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgSortFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_PartitionFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: *mut npy_intp,
                                                 arg5: *mut npy_intp,
                                                 arg6: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgPartitionFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: npy_intp,
                                                 arg5: *mut npy_intp,
                                                 arg6: *mut npy_intp,
                                                 arg7: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FillWithScalarFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ScalarKindFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FastClipFunc =
    ::std::option::Option<unsafe extern "C" fn(in_: *mut ::std::os::raw::c_void,
                                                 n_in: npy_intp,
                                                 min: *mut ::std::os::raw::c_void,
                                                 max: *mut ::std::os::raw::c_void,
                                                 out: *mut ::std::os::raw::c_void)>;
pub type PyArray_FastPutmaskFunc =
    ::std::option::Option<unsafe extern "C" fn(in_: *mut ::std::os::raw::c_void,
                                                 mask: *mut ::std::os::raw::c_void,
                                                 n_in: npy_intp,
                                                 values: *mut ::std::os::raw::c_void,
                                                 nv: npy_intp)>;
pub type PyArray_FastTakeFunc =
    ::std::option::Option<unsafe extern "C" fn(dest: *mut ::std::os::raw::c_void,
                                                 src: *mut ::std::os::raw::c_void,
                                                 indarray: *mut npy_intp,
                                                 nindarray: npy_intp,
                                                 n_outer: npy_intp,
                                                 m_middle: npy_intp,
                                                 nelem: npy_intp,
                                                 clipmode: NPY_CLIPMODE)
                                                 -> ::std::os::raw::c_int>;
pub type NpyAuxData_FreeFunc = ::std::option::Option<unsafe extern "C" fn(arg1: *mut NpyAuxData)>;
pub type NpyAuxData_CloneFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut NpyAuxData) -> *mut NpyAuxData>;
<commit_msg>Clean up array.rs<commit_after>#![allow(non_camel_case_types)]

use libc::FILE;
use pyffi::*;
use super::types::*;

#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum NPY_CLIPMODE {
    NPY_CLIP = 0,
    NPY_WRAP = 1,
    NPY_RAISE = 2,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArrayFlagsObject {
    pub ob_base: PyObject,
    pub arr: *mut PyObject,
    pub flags: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArray_Dims {
    pub ptr: *mut npy_intp,
    pub len: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArray_Chunk {
    pub ob_base: PyObject,
    pub base: *mut PyObject,
    pub ptr: *mut ::std::os::raw::c_void,
    pub len: npy_intp,
    pub flags: ::std::os::raw::c_int,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct PyArrayInterface {
    pub two: ::std::os::raw::c_int,
    pub nd: ::std::os::raw::c_int,
    pub typekind: ::std::os::raw::c_char,
    pub itemsize: ::std::os::raw::c_int,
    pub flags: ::std::os::raw::c_int,
    pub shape: *mut npy_intp,
    pub strides: *mut npy_intp,
    pub data: *mut ::std::os::raw::c_void,
    pub descr: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArray_Descr {
    pub ob_base: PyObject,
    pub typeobj: *mut PyTypeObject,
    pub kind: ::std::os::raw::c_char,
    pub type_: ::std::os::raw::c_char,
    pub byteorder: ::std::os::raw::c_char,
    pub flags: ::std::os::raw::c_char,
    pub type_num: ::std::os::raw::c_int,
    pub elsize: ::std::os::raw::c_int,
    pub alignment: ::std::os::raw::c_int,
    pub subarray: *mut PyArrray_ArrayDescr,
    pub fields: *mut PyObject,
    pub names: *mut PyObject,
    pub f: *mut PyArray_ArrFuncs,
    pub metadata: *mut PyObject,
    pub c_metadata: *mut NpyAuxData,
    pub hash: npy_hash_t,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArrayObject {
    pub ob_base: PyObject,
    pub data: *mut ::std::os::raw::c_char,
    pub nd: ::std::os::raw::c_int,
    pub dimensions: *mut npy_intp,
    pub strides: *mut npy_intp,
    pub base: *mut PyObject,
    pub descr: *mut PyArray_Descr,
    pub flags: ::std::os::raw::c_int,
    pub weakreflist: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArrray_ArrayDescr {
    pub base: *mut PyArray_Descr,
    pub shape: *mut PyObject,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyArray_ArrFuncs {
    pub cast: [PyArray_VectorUnaryFunc; 21usize],
    pub getitem: PyArray_GetItemFunc,
    pub setitem: PyArray_SetItemFunc,
    pub copyswapn: PyArray_CopySwapNFunc,
    pub copyswap: PyArray_CopySwapFunc,
    pub compare: PyArray_CompareFunc,
    pub argmax: PyArray_ArgFunc,
    pub dotfunc: PyArray_DotFunc,
    pub scanfunc: PyArray_ScanFunc,
    pub fromstr: PyArray_FromStrFunc,
    pub nonzero: PyArray_NonzeroFunc,
    pub fill: PyArray_FillFunc,
    pub fillwithscalar: PyArray_FillWithScalarFunc,
    pub sort: [PyArray_SortFunc; 3usize],
    pub argsort: [PyArray_ArgSortFunc; 3usize],
    pub castdict: *mut PyObject,
    pub scalarkind: PyArray_ScalarKindFunc,
    pub cancastscalarkindto: *mut *mut ::std::os::raw::c_int,
    pub cancastto: *mut ::std::os::raw::c_int,
    pub fastclip: PyArray_FastClipFunc,
    pub fastputmask: PyArray_FastPutmaskFunc,
    pub fasttake: PyArray_FastTakeFunc,
    pub argmin: PyArray_ArgFunc,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct NpyAuxData {
    pub free: NpyAuxData_FreeFunc,
    pub clone: NpyAuxData_CloneFunc,
    pub reserved: [*mut ::std::os::raw::c_void; 2usize],
}

pub type PyArray_GetItemFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void)
                                                 -> *mut PyObject>;
pub type PyArray_SetItemFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut PyObject,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_CopySwapNFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: npy_intp,
                                                 arg5: npy_intp,
                                                 arg6: ::std::os::raw::c_int,
                                                 arg7: *mut ::std::os::raw::c_void)>;
pub type PyArray_CopySwapFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: ::std::os::raw::c_int,
                                                 arg4: *mut ::std::os::raw::c_void)>;
pub type PyArray_NonzeroFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_uchar>;
pub type PyArray_CompareFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *const ::std::os::raw::c_void,
                                                 arg2: *const ::std::os::raw::c_void,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_DotFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: npy_intp,
                                                 arg5: *mut ::std::os::raw::c_void,
                                                 arg6: npy_intp,
                                                 arg7: *mut ::std::os::raw::c_void)>;
pub type PyArray_VectorUnaryFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut ::std::os::raw::c_void,
                                                 arg3: npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void,
                                                 arg5: *mut ::std::os::raw::c_void)>;
pub type PyArray_ScanFunc =
    ::std::option::Option<unsafe extern "C" fn(fp: *mut FILE,
                                                 dptr: *mut ::std::os::raw::c_void,
                                                 ignore: *mut ::std::os::raw::c_char,
                                                 arg1: *mut PyArray_Descr)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FromStrFunc =
    ::std::option::Option<unsafe extern "C" fn(s: *mut ::std::os::raw::c_char,
                                                 dptr: *mut ::std::os::raw::c_void,
                                                 endptr: *mut *mut ::std::os::raw::c_char,
                                                 arg1: *mut PyArray_Descr)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FillFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_SortFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgSortFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_PartitionFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: *mut npy_intp,
                                                 arg5: *mut npy_intp,
                                                 arg6: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ArgPartitionFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: *mut npy_intp,
                                                 arg3: npy_intp,
                                                 arg4: npy_intp,
                                                 arg5: *mut npy_intp,
                                                 arg6: *mut npy_intp,
                                                 arg7: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FillWithScalarFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void,
                                                 arg2: npy_intp,
                                                 arg3: *mut ::std::os::raw::c_void,
                                                 arg4: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_ScalarKindFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void)
                                                 -> ::std::os::raw::c_int>;
pub type PyArray_FastClipFunc =
    ::std::option::Option<unsafe extern "C" fn(in_: *mut ::std::os::raw::c_void,
                                                 n_in: npy_intp,
                                                 min: *mut ::std::os::raw::c_void,
                                                 max: *mut ::std::os::raw::c_void,
                                                 out: *mut ::std::os::raw::c_void)>;
pub type PyArray_FastPutmaskFunc =
    ::std::option::Option<unsafe extern "C" fn(in_: *mut ::std::os::raw::c_void,
                                                 mask: *mut ::std::os::raw::c_void,
                                                 n_in: npy_intp,
                                                 values: *mut ::std::os::raw::c_void,
                                                 nv: npy_intp)>;
pub type PyArray_FastTakeFunc =
    ::std::option::Option<unsafe extern "C" fn(dest: *mut ::std::os::raw::c_void,
                                                 src: *mut ::std::os::raw::c_void,
                                                 indarray: *mut npy_intp,
                                                 nindarray: npy_intp,
                                                 n_outer: npy_intp,
                                                 m_middle: npy_intp,
                                                 nelem: npy_intp,
                                                 clipmode: NPY_CLIPMODE)
                                                 -> ::std::os::raw::c_int>;
pub type NpyAuxData_FreeFunc = ::std::option::Option<unsafe extern "C" fn(arg1: *mut NpyAuxData)>;
pub type NpyAuxData_CloneFunc =
    ::std::option::Option<unsafe extern "C" fn(arg1: *mut NpyAuxData) -> *mut NpyAuxData>;
<|endoftext|>


<commit_before>#![warn(clippy::same_item_push)]

const VALUE: u8 = 7;

fn mutate_increment(x: &mut u8) -> u8 {
    *x += 1;
    *x
}

fn increment(x: u8) -> u8 {
    x + 1
}

fn main() {
    // Test for basic case
    let mut spaces = Vec::with_capacity(10);
    for _ in 0..10 {
        spaces.push(vec![b' ']);
    }

    let mut vec2: Vec<u8> = Vec::new();
    let item = 2;
    for _ in 5..=20 {
        vec2.push(item);
    }

    let mut vec3: Vec<u8> = Vec::new();
    for _ in 0..15 {
        let item = 2;
        vec3.push(item);
    }

    let mut vec4: Vec<u8> = Vec::new();
    for _ in 0..15 {
        vec4.push(13);
    }

    // Suggestion should not be given as pushed variable can mutate
    let mut vec5: Vec<u8> = Vec::new();
    let mut item: u8 = 2;
    for _ in 0..30 {
        vec5.push(mutate_increment(&mut item));
    }

    let mut vec6: Vec<u8> = Vec::new();
    let mut item: u8 = 2;
    let mut item2 = &mut mutate_increment(&mut item);
    for _ in 0..30 {
        vec6.push(mutate_increment(item2));
    }

    let mut vec7: Vec<usize> = Vec::new();
    for (a, b) in [0, 1, 4, 9, 16].iter().enumerate() {
        vec7.push(a);
    }

    let mut vec8: Vec<u8> = Vec::new();
    for i in 0..30 {
        vec8.push(increment(i));
    }

    let mut vec9: Vec<u8> = Vec::new();
    for i in 0..30 {
        vec9.push(i + i * i);
    }

    // Suggestion should not be given as there are multiple pushes that are not the same
    let mut vec10: Vec<u8> = Vec::new();
    let item: u8 = 2;
    for _ in 0..30 {
        vec10.push(item);
        vec10.push(item * 2);
    }

    // Suggestion should not be given as Vec is not involved
    for _ in 0..5 {
        println!("Same Item Push");
    }

    struct A {
        kind: u32,
    }
    let mut vec_a: Vec<A> = Vec::new();
    for i in 0..30 {
        vec_a.push(A { kind: i });
    }
    let mut vec12: Vec<u8> = Vec::new();
    for a in vec_a {
        vec12.push(2u8.pow(a.kind));
    }

    // Fix #5902
    let mut vec13: Vec<u8> = Vec::new();
    let mut item = 0;
    for _ in 0..10 {
        vec13.push(item);
        item += 10;
    }

    // Fix #5979
    let mut vec14: Vec<std::fs::File> = Vec::new();
    for _ in 0..10 {
        vec14.push(std::fs::File::open("foobar").unwrap());
    }
    // Fix #5979
    #[derive(Clone)]
    struct S {}

    trait T {}
    impl T for S {}

    let mut vec15: Vec<Box<dyn T>> = Vec::new();
    for _ in 0..10 {
        vec15.push(Box::new(S {}));
    }

    let mut vec16 = Vec::new();
    for _ in 0..20 {
        vec16.push(VALUE);
    }

    let mut vec17 = Vec::new();
    let item = VALUE;
    for _ in 0..20 {
        vec17.push(item);
    }
}
<commit_msg>Add some tests to `same_item_push`<commit_after>#![warn(clippy::same_item_push)]

const VALUE: u8 = 7;

fn mutate_increment(x: &mut u8) -> u8 {
    *x += 1;
    *x
}

fn increment(x: u8) -> u8 {
    x + 1
}

fn fun() -> usize {
    42
}

fn main() {
    // Test for basic case
    let mut spaces = Vec::with_capacity(10);
    for _ in 0..10 {
        spaces.push(vec![b' ']);
    }

    let mut vec2: Vec<u8> = Vec::new();
    let item = 2;
    for _ in 5..=20 {
        vec2.push(item);
    }

    let mut vec3: Vec<u8> = Vec::new();
    for _ in 0..15 {
        let item = 2;
        vec3.push(item);
    }

    let mut vec4: Vec<u8> = Vec::new();
    for _ in 0..15 {
        vec4.push(13);
    }

    // Suggestion should not be given as pushed variable can mutate
    let mut vec5: Vec<u8> = Vec::new();
    let mut item: u8 = 2;
    for _ in 0..30 {
        vec5.push(mutate_increment(&mut item));
    }

    let mut vec6: Vec<u8> = Vec::new();
    let mut item: u8 = 2;
    let mut item2 = &mut mutate_increment(&mut item);
    for _ in 0..30 {
        vec6.push(mutate_increment(item2));
    }

    let mut vec7: Vec<usize> = Vec::new();
    for (a, b) in [0, 1, 4, 9, 16].iter().enumerate() {
        vec7.push(a);
    }

    let mut vec8: Vec<u8> = Vec::new();
    for i in 0..30 {
        vec8.push(increment(i));
    }

    let mut vec9: Vec<u8> = Vec::new();
    for i in 0..30 {
        vec9.push(i + i * i);
    }

    // Suggestion should not be given as there are multiple pushes that are not the same
    let mut vec10: Vec<u8> = Vec::new();
    let item: u8 = 2;
    for _ in 0..30 {
        vec10.push(item);
        vec10.push(item * 2);
    }

    // Suggestion should not be given as Vec is not involved
    for _ in 0..5 {
        println!("Same Item Push");
    }

    struct A {
        kind: u32,
    }
    let mut vec_a: Vec<A> = Vec::new();
    for i in 0..30 {
        vec_a.push(A { kind: i });
    }
    let mut vec12: Vec<u8> = Vec::new();
    for a in vec_a {
        vec12.push(2u8.pow(a.kind));
    }

    // Fix #5902
    let mut vec13: Vec<u8> = Vec::new();
    let mut item = 0;
    for _ in 0..10 {
        vec13.push(item);
        item += 10;
    }

    // Fix #5979
    let mut vec14: Vec<std::fs::File> = Vec::new();
    for _ in 0..10 {
        vec14.push(std::fs::File::open("foobar").unwrap());
    }
    // Fix #5979
    #[derive(Clone)]
    struct S {}

    trait T {}
    impl T for S {}

    let mut vec15: Vec<Box<dyn T>> = Vec::new();
    for _ in 0..10 {
        vec15.push(Box::new(S {}));
    }

    let mut vec16 = Vec::new();
    for _ in 0..20 {
        vec16.push(VALUE);
    }

    let mut vec17 = Vec::new();
    let item = VALUE;
    for _ in 0..20 {
        vec17.push(item);
    }

    let mut vec18 = Vec::new();
    let item = 42;
    let item = fun();
    for _ in 0..20 {
        vec18.push(item);
    }

    let mut vec19 = Vec::new();
    let key = 1;
    for _ in 0..20 {
        let item = match key {
            1 => 10,
            _ => 0,
        };
        vec19.push(item);
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;

fn main()
{
    let context = sdl2::init().unwrap();
    let video = context.video().unwrap();

    let window = video.window("rrthozopsi", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();
    let mut event_pump = context.event_pump().unwrap();

    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                Event::KeyDown {..} => {
                    renderer.set_draw_color(sdl2::pixels::Color::RGB(255, 0, 0));
                    renderer.clear();
                    renderer.present();
                },
                _ => {}
            }
        }
    }
}
<commit_msg>Build fix<commit_after>extern crate sdl2;

use sdl2::event::Event;
use sdl2::keyboard::Keycode;

fn main()
{
    let context = sdl2::init().unwrap();
    let video = context.video().unwrap();

    let window = video.window("rrthozopsi", 800, 600)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    let mut renderer = window.renderer().build().unwrap();
    let mut event_pump = context.event_pump().unwrap();

    'running: loop {
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                Event::KeyDown {..} => {
                    renderer.set_draw_color(sdl2::pixels::Color::RGB(255, 0, 0));
                    renderer.clear();
                    renderer.present();
                },
                _ => {}
            }
        }
    }
}
<|endoftext|>