<commit_before>extern crate thoughtfuck;

mod common;

use common::FauxStdout;
use thoughtfuck::vm::*;
use thoughtfuck::program::*;
use thoughtfuck::parse::parse;

#[test]
fn hello_world () {
    const SOURCE: &str = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
    let commands = parse(SOURCE);

    let mut program = Program::new();
    program.append(&commands);

    let mut stdout = FauxStdout::new();
    {
        let mut vm = VM::new(&mut stdout);
        program.execute(&mut vm);
    }
    assert_eq!(stdout.buffer, "Hello World!\n");
}
<commit_msg>Add read_file integration helper function<commit_after>extern crate thoughtfuck;

mod common;

use std::fs::File;
use std::io::Read;

use common::FauxStdout;
use thoughtfuck::vm::*;
use thoughtfuck::program::*;
use thoughtfuck::parse::parse;

fn read_file(filename: &str) -> String {
    let mut file = File::open(filename).unwrap();
    let mut source = String::new();
    file.read_to_string(&mut source).unwrap();
    source
}

#[test]
fn hello_world () {
    const SOURCE: &str = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
    let commands = parse(SOURCE);

    let mut program = Program::new();
    program.append(&commands);

    let mut stdout = FauxStdout::new();
    {
        let mut vm = VM::new(&mut stdout);
        program.execute(&mut vm);
    }
    assert_eq!(stdout.buffer, "Hello World!\n");
}
<|endoftext|>


<commit_before>/// Connexion that can receive packets from multiple endpoints.
///
/// This is just a placeholder object. In order for it to receive packets it
/// must be added to a conn::Manager.
pub struct MultiConn;
<commit_msg>net/conn: Add implementation of MultiConn<commit_after>use vec_deque::VecDeque;

use sync::spin::SpinLock;

use thread::WaitQueue;

use net::{InterfaceWeak, Packet, PacketBuilder};

use net::defs::Rule;

/// Connexion that can receive packets from multiple endpoints.
///
/// This is just a placeholder object. In order for it to receive packets it
/// must be added to a `Manager`.
pub struct MultiConn {
    queue: SpinLock<VecDeque<(Packet, Rule)>>,
    wait: WaitQueue,
    parent: InterfaceWeak,
}

unsafe impl Sync for MultiConn {}

impl MultiConn {
    /// Create a new multi connexion object.
    ///
    /// This should not be used directly. Instead, to create a new multi
    /// connexion, use `Interface::create_multi()`.
    pub fn new(parent: InterfaceWeak) -> Self {
        MultiConn {
            queue: SpinLock::new(VecDeque::new()),
            wait: WaitQueue::new(),
            parent: parent,
        }
    }

    /// Pop a packet from the connexion.
    ///
    /// It returns a tuple that contains the packet and a rule that contains
    /// information to reply to the sender.
    ///
    /// Note that if no packets are available, this function will block until
    /// one is received.
    pub fn pop_packet(&self) -> (Packet, Rule) {
        loop {
            let res = self.queue.lock().pop_front();

            match res {
                None => wait_event!(self.wait, !self.queue.lock().is_empty()),
                Some(res) => return res,
            }
        }
    }

    /// Insert a packet inside the connexion
    ///
    /// `pkt` is the received packet
    ///
    /// `rule` is information about the endpoint that sent the packet
    pub fn rx(&self, pkt: Packet, rule: Rule) {
        self.queue.lock().push_back((pkt, rule));
        self.wait.unblock();
    }

    /// Send data through the connexion.
    ///
    /// Since a multi connexion does not target a specific endpoint you have
    /// to pass a `rule` to tell the connexion the endpoint the packet has to
    /// be sent to.
    pub fn tx(&self, data: &[u8], rule: &Rule) -> Result<(), ()> {
        let mut builder = try!(PacketBuilder::new());

        try!(builder.write(data));

        self.tx_packet(builder, rule)
    }

    /// Send a packet through the connexion.
    ///
    /// It might ease the pain of some data sender to use directly a
    /// `PacketBuilder` and send this directly without using a slice.
    ///
    /// Since a multi connexion does not target a specific endpoint you have
    /// to pass a `rule` to tell the connexion the endpoint the packet has to
    /// be sent to.
    pub fn tx_packet(&self, builder: PacketBuilder,
                     rule: &Rule) -> Result<(), ()> {
        let intf = try!(self.parent.upgrade().ok_or(()));

        intf.tx_packet(builder, rule)
    }
}

impl Drop for MultiConn {
    fn drop(&mut self) {
        // XXX: The way multi connexion should go down is not defined yet.
        // This will eventually trigger when it's time to seriously think
        // about it
        unimplemented!();
    }
}
<|endoftext|>


<commit_before>use std::default::Default;
use std::fs;
use std::path::Path;

use core::{Profiles, Workspace};
use util::Config;
use util::errors::{CargoResult, CargoResultExt};
use util::paths;
use ops::{self, BuildConfig, Context, Kind, Unit};

pub struct CleanOptions<'a> {
    pub config: &'a Config,
    pub spec: Vec<String>,
    pub target: Option<String>,
    pub release: bool,
}

/// Cleans the project from build artifacts.
pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
    let target_dir = ws.target_dir();
    let config = ws.config();

    // If we have a spec, then we need to delete some packages, otherwise, just
    // remove the whole target directory and be done with it!
    //
    // Note that we don't bother grabbing a lock here as we're just going to
    // blow it all away anyway.
    if opts.spec.is_empty() {
        let target_dir = target_dir.into_path_unlocked();
        return rm_rf(&target_dir, config);
    }

    let (packages, resolve) = ops::resolve_ws(ws)?;

    let profiles = ws.profiles();
    let host_triple = opts.config.rustc()?.host.clone();
    let mut cx = Context::new(
        ws,
        &resolve,
        &packages,
        opts.config,
        BuildConfig {
            host_triple,
            requested_target: opts.target.clone(),
            release: opts.release,
            jobs: 1,
            ..BuildConfig::default()
        },
        profiles,
    )?;
    let mut units = Vec::new();

    for spec in opts.spec.iter() {
        // Translate the spec to a Package
        let pkgid = resolve.query(spec)?;
        let pkg = packages.get(pkgid)?;

        // Generate all relevant `Unit` targets for this package
        for target in pkg.targets() {
            for kind in [Kind::Host, Kind::Target].iter() {
                let Profiles {
                    ref release,
                    ref dev,
                    ref test,
                    ref bench,
                    ref doc,
                    ref custom_build,
                    ref test_deps,
                    ref bench_deps,
                    ref check,
                    ref check_test,
                    ref doctest,
                } = *profiles;
                let profiles = [
                    release,
                    dev,
                    test,
                    bench,
                    doc,
                    custom_build,
                    test_deps,
                    bench_deps,
                    check,
                    check_test,
                    doctest,
                ];
                for profile in profiles.iter() {
                    units.push(Unit {
                        pkg,
                        target,
                        profile,
                        kind: *kind,
                    });
                }
            }
        }
    }

    cx.probe_target_info(&units)?;

    for unit in units.iter() {
        rm_rf(&cx.fingerprint_dir(unit), config)?;
        if unit.target.is_custom_build() {
            if unit.profile.run_custom_build {
                rm_rf(&cx.build_script_out_dir(unit), config)?;
            } else {
                rm_rf(&cx.build_script_dir(unit), config)?;
            }
            continue;
        }

        for &(ref src, ref link_dst, _) in cx.target_filenames(unit)?.iter() {
            rm_rf(src, config)?;
            if let Some(ref dst) = *link_dst {
                rm_rf(dst, config)?;
            }
        }
    }

    Ok(())
}

fn rm_rf(path: &Path, config: &Config) -> CargoResult<()> {
    let m = fs::metadata(path);
    if m.as_ref().map(|s| s.is_dir()).unwrap_or(false) {
        config
            .shell()
            .verbose(|shell| shell.status("Removing", path.display()))?;
        paths::remove_dir_all(path).chain_err(|| format_err!("could not remove build directory"))?;
    } else if m.is_ok() {
        config
            .shell()
            .verbose(|shell| shell.status("Removing", path.display()))?;
        paths::remove_file(path).chain_err(|| format_err!("failed to remove build artifact"))?;
    }
    Ok(())
}
<commit_msg>Auto merge of #5222 - AdamNiederer:patch-1, r=matklad<commit_after>use std::default::Default;
use std::fs;
use std::path::Path;

use core::{Profiles, Workspace};
use util::Config;
use util::errors::{CargoResult, CargoResultExt};
use util::paths;
use ops::{self, BuildConfig, Context, Kind, Unit};

pub struct CleanOptions<'a> {
    pub config: &'a Config,
    /// A list of packages to clean. If empty, everything is cleaned.
    pub spec: Vec<String>,
    /// The target arch triple to clean, or None for the host arch
    pub target: Option<String>,
    /// Whether to clean the release directory
    pub release: bool,
}

/// Cleans the project from build artifacts.
pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
    let target_dir = ws.target_dir();
    let config = ws.config();

    // If we have a spec, then we need to delete some packages, otherwise, just
    // remove the whole target directory and be done with it!
    //
    // Note that we don't bother grabbing a lock here as we're just going to
    // blow it all away anyway.
    if opts.spec.is_empty() {
        let target_dir = target_dir.into_path_unlocked();
        return rm_rf(&target_dir, config);
    }

    let (packages, resolve) = ops::resolve_ws(ws)?;

    let profiles = ws.profiles();
    let host_triple = opts.config.rustc()?.host.clone();
    let mut cx = Context::new(
        ws,
        &resolve,
        &packages,
        opts.config,
        BuildConfig {
            host_triple,
            requested_target: opts.target.clone(),
            release: opts.release,
            jobs: 1,
            ..BuildConfig::default()
        },
        profiles,
    )?;
    let mut units = Vec::new();

    for spec in opts.spec.iter() {
        // Translate the spec to a Package
        let pkgid = resolve.query(spec)?;
        let pkg = packages.get(pkgid)?;

        // Generate all relevant `Unit` targets for this package
        for target in pkg.targets() {
            for kind in [Kind::Host, Kind::Target].iter() {
                let Profiles {
                    ref release,
                    ref dev,
                    ref test,
                    ref bench,
                    ref doc,
                    ref custom_build,
                    ref test_deps,
                    ref bench_deps,
                    ref check,
                    ref check_test,
                    ref doctest,
                } = *profiles;
                let profiles = [
                    release,
                    dev,
                    test,
                    bench,
                    doc,
                    custom_build,
                    test_deps,
                    bench_deps,
                    check,
                    check_test,
                    doctest,
                ];
                for profile in profiles.iter() {
                    units.push(Unit {
                        pkg,
                        target,
                        profile,
                        kind: *kind,
                    });
                }
            }
        }
    }

    cx.probe_target_info(&units)?;

    for unit in units.iter() {
        rm_rf(&cx.fingerprint_dir(unit), config)?;
        if unit.target.is_custom_build() {
            if unit.profile.run_custom_build {
                rm_rf(&cx.build_script_out_dir(unit), config)?;
            } else {
                rm_rf(&cx.build_script_dir(unit), config)?;
            }
            continue;
        }

        for &(ref src, ref link_dst, _) in cx.target_filenames(unit)?.iter() {
            rm_rf(src, config)?;
            if let Some(ref dst) = *link_dst {
                rm_rf(dst, config)?;
            }
        }
    }

    Ok(())
}

fn rm_rf(path: &Path, config: &Config) -> CargoResult<()> {
    let m = fs::metadata(path);
    if m.as_ref().map(|s| s.is_dir()).unwrap_or(false) {
        config
            .shell()
            .verbose(|shell| shell.status("Removing", path.display()))?;
        paths::remove_dir_all(path).chain_err(|| format_err!("could not remove build directory"))?;
    } else if m.is_ok() {
        config
            .shell()
            .verbose(|shell| shell.status("Removing", path.display()))?;
        paths::remove_file(path).chain_err(|| format_err!("failed to remove build artifact"))?;
    }
    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate serde_yaml;
extern crate fnv;
#[macro_use]
extern crate lutario;
extern crate netlib_src;

use std::fs::{self, File};
use fnv::FnvHashMap;
use lutario::{hf, nuclei, qdpt};
use lutario::basis::occ;
use lutario::j_scheme::JAtlas;
use lutario::op::Op;
use lutario::utils::Toler;

const TOLER: Toler = Toler { relerr: 1e-13, abserr: 1e-13 };

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Results {
    pub de_dqdpt2: FnvHashMap<nuclei::Npjw, f64>,
    pub e_hf: f64,
    pub de_mp2: f64,
}

fn calc_j(
    nucleus: nuclei::Nucleus,
    omega: f64,
    two_body_mat_elems: &FnvHashMap<nuclei::JNpjw2Pair, f64>,
) -> Results {
    let atlas = JAtlas::new(&mut nucleus.jpwn_orbs().into_iter());
    let scheme = atlas.scheme();
    let h1 = nuclei::make_ho3d_op_j(&atlas, omega);
    let h2 = nuclei::make_v_op_j(&atlas, two_body_mat_elems);

    let mut r = Op::new_vec(scheme.clone());
    qdpt::dqdpt2_term3(&h1, &h2, &mut r);
    qdpt::dqdpt2_term4(&h1, &h2, &mut r);
    let mut de_dqdpt2 = FnvHashMap::default();
    for p in scheme.states_10(&occ::ALL1) {
        let npjw = nuclei::Npjw::from(atlas.decode(p).unwrap());
        let value = r.at(p, p);
        if !value.is_finite() {
            continue;
        }
        assert!(de_dqdpt2.insert(npjw, value).is_none());
    }

    let mut hf = hf::HfConf {
        toler: TOLER,
        .. Default::default()
    }.new_run(&h1, &h2);
    hf.do_run().unwrap();
    let mut hh1 = Op::new(scheme.clone());
    let mut hh2 = Op::new(scheme.clone());
    hf::transform_h1(&h1, &hf.dcoeff, &mut hh1);
    hf::transform_h2(&h2, &hf.dcoeff, &mut hh2);
    let mut hn0 = 0.0;
    let mut hn1 = Op::new(scheme.clone());
    let mut hn2 = Op::new(scheme.clone());
    hf::normord(&hh1, &hh2, &mut hn0, &mut hn1, &mut hn2);
    let de_mp2 = qdpt::mp2(&hn1, &hn2);
    Results {
        de_dqdpt2,
        e_hf: hn0,
        de_mp2,
    }
}

fn calc_m(
    nucleus: nuclei::Nucleus,
    omega: f64,
    two_body_mat_elems: &FnvHashMap<nuclei::JNpjw2Pair, f64>,
) -> Results {
    let atlas = JAtlas::new(&mut nucleus.pmwnj_orbs().into_iter());
    let scheme = atlas.scheme();
    let h1 = nuclei::make_ho3d_op_m(&atlas, omega);
    let h2 = nuclei::make_v_op_m(&atlas, two_body_mat_elems);

    let mut r = Op::new_vec(scheme.clone());
    qdpt::dqdpt2_term3(&h1, &h2, &mut r);
    qdpt::dqdpt2_term4(&h1, &h2, &mut r);
    let mut de_dqdpt2 = FnvHashMap::default();
    for p in scheme.states_10(&occ::ALL1) {
        let npjmw = nuclei::Npjmw::from(atlas.decode(p).unwrap());
        let npjw = nuclei::Npjw::from(npjmw);
        let value = r.at(p, p);
        if !value.is_finite() {
            continue;
        }
        toler_assert_eq!(TOLER, *de_dqdpt2.entry(npjw).or_insert(value), value);
    }

    let mut hf = hf::HfConf {
        toler: TOLER,
        .. Default::default()
    }.new_run(&h1, &h2);
    hf.do_run().unwrap();
    let mut hh1 = Op::new(scheme.clone());
    let mut hh2 = Op::new(scheme.clone());
    hf::transform_h1(&h1, &hf.dcoeff, &mut hh1);
    hf::transform_h2(&h2, &hf.dcoeff, &mut hh2);
    let mut hn0 = 0.0;
    let mut hn1 = Op::new(scheme.clone());
    let mut hn2 = Op::new(scheme.clone());
    hf::normord(&hh1, &hh2, &mut hn0, &mut hn1, &mut hn2);
    let de_mp2 = qdpt::mp2(&hn1, &hn2);

    Results {
        de_dqdpt2,
        e_hf: hn0,
        de_mp2,
    }
}

#[test]
fn test_nuclei() {
    let omega = 24.0;
    let basis_spec = nuclei::NucleonBasisSpec::with_e_max(2);
    let nucleus = nuclei::Nucleus {
        neutron_basis_spec: basis_spec,
        proton_basis_spec: basis_spec,
        e_fermi_neutron: 2,
        e_fermi_proton: 2,
    };
    let two_body_mat_elems = nuclei::morten_vint::LoadTwoBodyMatElems {
        sp_table_path: "data/cens-mbpt/spox16.dat".as_ref(),
        vint_table_path: "data/cens-mbpt/vintnn3lohw24.dat".as_ref(),
    }.call().unwrap();
    let j_results = calc_j(nucleus, omega, &two_body_mat_elems);
    let m_results = calc_m(nucleus, omega, &two_body_mat_elems);
    for npjw in nucleus.npjw_orbs() {
        if !j_results.de_dqdpt2.contains_key(&npjw)
            && !m_results.de_dqdpt2.contains_key(&npjw)
        {
            continue;
        }
        let xj = *j_results.de_dqdpt2.get(&npjw).unwrap();
        let xm = *m_results.de_dqdpt2.get(&npjw).unwrap();
        toler_assert_eq!(TOLER, xj, xm);
    }
    toler_assert_eq!(TOLER, j_results.e_hf, m_results.e_hf);
    toler_assert_eq!(TOLER, j_results.de_mp2, m_results.de_mp2);
    fs::create_dir_all("out").unwrap();
    serde_yaml::to_writer(
        File::create("out/test_nuclei").unwrap(),
        &j_results,
    ).unwrap();
}
<commit_msg>test_nuclei: name data files by system<commit_after>#[macro_use]
extern crate serde_derive;
extern crate serde_yaml;
extern crate fnv;
#[macro_use]
extern crate lutario;
extern crate netlib_src;

use std::fs::{self, File};
use std::io::Write;
use fnv::FnvHashMap;
use lutario::{hf, nuclei, qdpt};
use lutario::basis::occ;
use lutario::j_scheme::JAtlas;
use lutario::op::Op;
use lutario::utils::Toler;

const TOLER: Toler = Toler { relerr: 1e-13, abserr: 1e-13 };

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Results {
    pub de_dqdpt2: FnvHashMap<nuclei::Npjw, f64>,
    pub e_hf: f64,
    pub de_mp2: f64,
}

fn calc_j(
    nucleus: nuclei::Nucleus,
    omega: f64,
    two_body_mat_elems: &FnvHashMap<nuclei::JNpjw2Pair, f64>,
) -> Results {
    let atlas = JAtlas::new(&mut nucleus.jpwn_orbs().into_iter());
    let scheme = atlas.scheme();
    let h1 = nuclei::make_ho3d_op_j(&atlas, omega);
    let h2 = nuclei::make_v_op_j(&atlas, two_body_mat_elems);

    let mut r = Op::new_vec(scheme.clone());
    qdpt::dqdpt2_term3(&h1, &h2, &mut r);
    qdpt::dqdpt2_term4(&h1, &h2, &mut r);
    let mut de_dqdpt2 = FnvHashMap::default();
    for p in scheme.states_10(&occ::ALL1) {
        let npjw = nuclei::Npjw::from(atlas.decode(p).unwrap());
        let value = r.at(p, p);
        if !value.is_finite() {
            continue;
        }
        assert!(de_dqdpt2.insert(npjw, value).is_none());
    }

    let mut hf = hf::HfConf {
        toler: TOLER,
        .. Default::default()
    }.new_run(&h1, &h2);
    hf.do_run().unwrap();
    let mut hh1 = Op::new(scheme.clone());
    let mut hh2 = Op::new(scheme.clone());
    hf::transform_h1(&h1, &hf.dcoeff, &mut hh1);
    hf::transform_h2(&h2, &hf.dcoeff, &mut hh2);
    let mut hn0 = 0.0;
    let mut hn1 = Op::new(scheme.clone());
    let mut hn2 = Op::new(scheme.clone());
    hf::normord(&hh1, &hh2, &mut hn0, &mut hn1, &mut hn2);
    let de_mp2 = qdpt::mp2(&hn1, &hn2);
    Results {
        de_dqdpt2,
        e_hf: hn0,
        de_mp2,
    }
}

fn calc_m(
    nucleus: nuclei::Nucleus,
    omega: f64,
    two_body_mat_elems: &FnvHashMap<nuclei::JNpjw2Pair, f64>,
) -> Results {
    let atlas = JAtlas::new(&mut nucleus.pmwnj_orbs().into_iter());
    let scheme = atlas.scheme();
    let h1 = nuclei::make_ho3d_op_m(&atlas, omega);
    let h2 = nuclei::make_v_op_m(&atlas, two_body_mat_elems);

    let mut r = Op::new_vec(scheme.clone());
    qdpt::dqdpt2_term3(&h1, &h2, &mut r);
    qdpt::dqdpt2_term4(&h1, &h2, &mut r);
    let mut de_dqdpt2 = FnvHashMap::default();
    for p in scheme.states_10(&occ::ALL1) {
        let npjmw = nuclei::Npjmw::from(atlas.decode(p).unwrap());
        let npjw = nuclei::Npjw::from(npjmw);
        let value = r.at(p, p);
        if !value.is_finite() {
            continue;
        }
        toler_assert_eq!(TOLER, *de_dqdpt2.entry(npjw).or_insert(value), value);
    }

    let mut hf = hf::HfConf {
        toler: TOLER,
        .. Default::default()
    }.new_run(&h1, &h2);
    hf.do_run().unwrap();
    let mut hh1 = Op::new(scheme.clone());
    let mut hh2 = Op::new(scheme.clone());
    hf::transform_h1(&h1, &hf.dcoeff, &mut hh1);
    hf::transform_h2(&h2, &hf.dcoeff, &mut hh2);
    let mut hn0 = 0.0;
    let mut hn1 = Op::new(scheme.clone());
    let mut hn2 = Op::new(scheme.clone());
    hf::normord(&hh1, &hh2, &mut hn0, &mut hn1, &mut hn2);
    let de_mp2 = qdpt::mp2(&hn1, &hn2);

    Results {
        de_dqdpt2,
        e_hf: hn0,
        de_mp2,
    }
}

#[test]
fn test_nuclei() {
    let omega = 24.0;
    let e_max = 2;
    let basis_spec = nuclei::NucleonBasisSpec::with_e_max(e_max);
    let nucleus = nuclei::Nucleus {
        neutron_basis_spec: basis_spec,
        proton_basis_spec: basis_spec,
        e_fermi_neutron: 2,
        e_fermi_proton: 2,
    };
    let two_body_mat_elems = nuclei::morten_vint::LoadTwoBodyMatElems {
        sp_table_path: "data/cens-mbpt/spox16.dat".as_ref(),
        vint_table_path: "data/cens-mbpt/vintnn3lohw24.dat".as_ref(),
    }.call().unwrap();
    let suffix = format!("ho-n3lo_omega={}_emax={}_en={}_ep={}.txt",
                         omega,
                         e_max,
                         nucleus.e_fermi_neutron,
                         nucleus.e_fermi_proton);
    let j_results = calc_j(nucleus, omega, &two_body_mat_elems);
    let m_results = calc_m(nucleus, omega, &two_body_mat_elems);
    for npjw in nucleus.npjw_orbs() {
        if !j_results.de_dqdpt2.contains_key(&npjw)
            && !m_results.de_dqdpt2.contains_key(&npjw)
        {
            continue;
        }
        let xj = *j_results.de_dqdpt2.get(&npjw).unwrap();
        let xm = *m_results.de_dqdpt2.get(&npjw).unwrap();
        toler_assert_eq!(TOLER, xj, xm);
    }
    toler_assert_eq!(TOLER, j_results.e_hf, m_results.e_hf);
    toler_assert_eq!(TOLER, j_results.de_mp2, m_results.de_mp2);
    fs::create_dir_all("out").unwrap();
    let mut f = File::create(&format!("out/test_nuclei_{}", suffix)).unwrap();
    serde_yaml::to_writer(&mut f, &j_results).unwrap();
    writeln!(f, "").unwrap();
}
<|endoftext|>


<commit_before>use crate::rust::{vec::Vec, string::String};
use crate::io;

use super::{Deserialize, Error, Module, Serialize, VarUint32, VarUint7, Type};
use super::index_map::IndexMap;

const NAME_TYPE_MODULE: u8 = 0;
const NAME_TYPE_FUNCTION: u8 = 1;
const NAME_TYPE_LOCAL: u8 = 2;

/// Debug name information.
#[derive(Clone, Debug, PartialEq)]
pub struct NameSection {
	/// Module name subsection.
	module: Option<ModuleNameSubsection>,

	/// Function name subsection.
	functions: Option<FunctionNameSubsection>,

	/// Local name subsection.
	locals: Option<LocalNameSubsection>,
}

impl NameSection {
	/// Creates a new name section.
	pub fn new(module: Option<ModuleNameSubsection>,
                  functions: Option<FunctionNameSubsection>,
                  locals: Option<LocalNameSubsection>) -> Self {
		Self {
			module,
			functions,
			locals,
		}
	}

	/// Module name subsection of this section.
	pub fn module(&self) -> Option<&ModuleNameSubsection> {
		self.module.as_ref()
	}

	/// Module name subsection of this section (mutable).
	pub fn module_mut(&mut self) -> &mut Option<ModuleNameSubsection> {
		&mut self.module
	}

	/// Functions name subsection of this section.
	pub fn functions(&self) -> Option<&FunctionNameSubsection> {
		self.functions.as_ref()
	}

	/// Functions name subsection of this section (mutable).
	pub fn functions_mut(&mut self) -> &mut Option<FunctionNameSubsection> {
		&mut self.functions
	}

	/// Local name subsection of this section.
	pub fn locals(&self) -> Option<&LocalNameSubsection> {
		self.locals.as_ref()
	}

	/// Local name subsection of this section (mutable).
	pub fn locals_mut(&mut self) -> &mut Option<LocalNameSubsection> {
		&mut self.locals
	}
}

impl NameSection {
	/// Deserialize a name section.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<Self, Error> {
		let mut module_name: Option<ModuleNameSubsection> = None;
		let mut function_names: Option<FunctionNameSubsection> = None;
		let mut local_names: Option<LocalNameSubsection> = None;

		loop {
			let subsection_type: u8 = match VarUint7::deserialize(rdr) {
				Ok(raw_subsection_type) => raw_subsection_type.into(),
				// todo: be more selective detecting no more subsection
				Err(_) => { break; },
			};

			// deserialize the section size
			VarUint32::deserialize(rdr)?;

			match subsection_type {
				NAME_TYPE_MODULE => {
					if let Some(_) = module_name {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION));
					}
					module_name = Some(ModuleNameSubsection::deserialize(rdr)?);
				},

				NAME_TYPE_FUNCTION => {
					if let Some(_) = function_names {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION));
					}
					function_names = Some(FunctionNameSubsection::deserialize(module, rdr)?);
				},

				NAME_TYPE_LOCAL => {
					if let Some(_) = local_names {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_LOCAL));
					}
					local_names = Some(LocalNameSubsection::deserialize(module, rdr)?);
				},

				_ => return Err(Error::UnknownNameSubsectionType(subsection_type))
			};
		}

		Ok(Self {
			module: module_name,
			functions: function_names,
			locals: local_names,
		})
	}
}

impl Serialize for NameSection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		fn serialize_subsection<W: io::Write>(wtr: &mut W, name_type: u8, name_payload: &Vec<u8>) -> Result<(), Error> {
			VarUint7::from(name_type).serialize(wtr)?;
			VarUint32::from(name_payload.len()).serialize(wtr)?;
			wtr.write(name_payload).map_err(Into::into)
		}

		if let Some(module_name_subsection) = self.module {
			let mut buffer = vec![];
			module_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_MODULE, &buffer)?;
		}

		if let Some(function_name_subsection) = self.functions {
			let mut buffer = vec![];
			function_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_FUNCTION, &buffer)?;
		}

		if let Some(local_name_subsection) = self.locals {
			let mut buffer = vec![];
			local_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_LOCAL, &buffer)?;
		}

		Ok(())
	}
}

/// The name of this module.
#[derive(Clone, Debug, PartialEq)]
pub struct ModuleNameSubsection {
	name: String,
}

impl ModuleNameSubsection {
	/// Create a new module name section with the specified name.
	pub fn new<S: Into<String>>(name: S) -> ModuleNameSubsection {
		ModuleNameSubsection { name: name.into() }
	}

	/// The name of this module.
	pub fn name(&self) -> &str {
		&self.name
	}

	/// The name of this module (mutable).
	pub fn name_mut(&mut self) -> &mut String {
		&mut self.name
	}
}

impl Serialize for ModuleNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.name.serialize(wtr)
	}
}

impl Deserialize for ModuleNameSubsection {
	type Error = Error;

	fn deserialize<R: io::Read>(rdr: &mut R) -> Result<ModuleNameSubsection, Error> {
		let name = String::deserialize(rdr)?;
		Ok(ModuleNameSubsection { name })
	}
}

/// The names of the functions in this module.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FunctionNameSubsection {
	names: NameMap,
}

impl FunctionNameSubsection {
	/// A map from function indices to names.
	pub fn names(&self) -> &NameMap {
		&self.names
	}

	/// A map from function indices to names (mutable).
	pub fn names_mut(&mut self) -> &mut NameMap {
		&mut self.names
	}

	/// Deserialize names, making sure that all names correspond to functions.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<FunctionNameSubsection, Error> {
		let names = IndexMap::deserialize(module.functions_space(), rdr)?;
		Ok(FunctionNameSubsection { names })
	}
}

impl Serialize for FunctionNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.names.serialize(wtr)
	}
}

/// The names of the local variables in this module's functions.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct LocalNameSubsection {
	local_names: IndexMap<NameMap>,
}

impl LocalNameSubsection {
	/// A map from function indices to a map from variables indices to names.
	pub fn local_names(&self) -> &IndexMap<NameMap> {
		&self.local_names
	}

	/// A map from function indices to a map from variables indices to names
	/// (mutable).
	pub fn local_names_mut(&mut self) -> &mut IndexMap<NameMap> {
		&mut self.local_names
	}

	/// Deserialize names, making sure that all names correspond to local
	/// variables.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<LocalNameSubsection, Error> {
		let funcs = module.function_section().ok_or_else(|| {
			Error::Other("cannot deserialize local names without a function section")
		})?;
		let max_entry_space = funcs.entries().len();

		let max_signature_args = module
			.type_section()
			.map(|ts|
				ts.types()
					.iter()
					.map(|x| { let Type::Function(ref func) = *x; func.params().len() })
					.max()
					.unwrap_or(0))
			.unwrap_or(0);

		let max_locals = module
			.code_section()
			.map(|cs| cs.bodies().iter().map(|f| f.locals().len()).max().unwrap_or(0))
			.unwrap_or(0);

		let max_space = max_signature_args + max_locals;

		let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr);

		let local_names = IndexMap::deserialize_with(
			max_entry_space,
			&deserialize_locals,
			rdr,
		)?;
		Ok(LocalNameSubsection { local_names })
	}}

impl Serialize for LocalNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.local_names.serialize(wtr)
	}
}

/// A map from indices to names.
pub type NameMap = IndexMap<String>;

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

	// A helper function for the tests. Serialize a section, deserialize it,
	// and make sure it matches the original.
	fn serialize_test(original: NameSection) -> Vec<u8> {
		let mut buffer = vec![];
		original
			.serialize(&mut buffer)
			.expect("serialize error");
		buffer
		// todo: add deserialization to this test
	}

	#[test]
	fn serialize_module_name() {
		let module_name_subsection = ModuleNameSubsection::new("my_mod");
		let original = NameSection::new(Some(module_name_subsection), None, None);
		serialize_test(original.clone());
	}

	#[test]
	fn serialize_function_names() {
		let mut function_name_subsection = FunctionNameSubsection::default();
		function_name_subsection.names_mut().insert(0, "hello_world".to_string());
		let name_section = NameSection::new(None, Some(function_name_subsection), None);
		serialize_test(name_section);
	}

	#[test]
	fn serialize_local_names() {
		let mut local_name_subsection = LocalNameSubsection::default();
		let mut locals = NameMap::default();
		locals.insert(0, "msg".to_string());
		local_name_subsection.local_names_mut().insert(0, locals);

		let name_section = NameSection::new(None, None, Some(local_name_subsection));
		serialize_test(name_section);
	}

	#[test]
	fn serialize_all_subsections() {
		let module_name_subsection = ModuleNameSubsection::new("ModuleNameSubsection");

		let mut function_name_subsection = FunctionNameSubsection::default();
		function_name_subsection.names_mut().insert(0, "foo".to_string());
		function_name_subsection.names_mut().insert(1, "bar".to_string());

		let mut local_name_subsection = LocalNameSubsection::default();
		let mut locals = NameMap::default();
		locals.insert(0, "msg1".to_string());
		locals.insert(1, "msg2".to_string());
		local_name_subsection.local_names_mut().insert(0, locals);

		let name_section = NameSection::new(Some(module_name_subsection), Some(function_name_subsection), Some(local_name_subsection));
		serialize_test(name_section);
	}
}
<commit_msg>Fix LocalNameSubsection-parsing with imported functions<commit_after>use crate::rust::{vec::Vec, string::String};
use crate::io;

use super::{Deserialize, Error, Module, Serialize, VarUint32, VarUint7, Type};
use super::index_map::IndexMap;

const NAME_TYPE_MODULE: u8 = 0;
const NAME_TYPE_FUNCTION: u8 = 1;
const NAME_TYPE_LOCAL: u8 = 2;

/// Debug name information.
#[derive(Clone, Debug, PartialEq)]
pub struct NameSection {
	/// Module name subsection.
	module: Option<ModuleNameSubsection>,

	/// Function name subsection.
	functions: Option<FunctionNameSubsection>,

	/// Local name subsection.
	locals: Option<LocalNameSubsection>,
}

impl NameSection {
	/// Creates a new name section.
	pub fn new(module: Option<ModuleNameSubsection>,
                  functions: Option<FunctionNameSubsection>,
                  locals: Option<LocalNameSubsection>) -> Self {
		Self {
			module,
			functions,
			locals,
		}
	}

	/// Module name subsection of this section.
	pub fn module(&self) -> Option<&ModuleNameSubsection> {
		self.module.as_ref()
	}

	/// Module name subsection of this section (mutable).
	pub fn module_mut(&mut self) -> &mut Option<ModuleNameSubsection> {
		&mut self.module
	}

	/// Functions name subsection of this section.
	pub fn functions(&self) -> Option<&FunctionNameSubsection> {
		self.functions.as_ref()
	}

	/// Functions name subsection of this section (mutable).
	pub fn functions_mut(&mut self) -> &mut Option<FunctionNameSubsection> {
		&mut self.functions
	}

	/// Local name subsection of this section.
	pub fn locals(&self) -> Option<&LocalNameSubsection> {
		self.locals.as_ref()
	}

	/// Local name subsection of this section (mutable).
	pub fn locals_mut(&mut self) -> &mut Option<LocalNameSubsection> {
		&mut self.locals
	}
}

impl NameSection {
	/// Deserialize a name section.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<Self, Error> {
		let mut module_name: Option<ModuleNameSubsection> = None;
		let mut function_names: Option<FunctionNameSubsection> = None;
		let mut local_names: Option<LocalNameSubsection> = None;

		loop {
			let subsection_type: u8 = match VarUint7::deserialize(rdr) {
				Ok(raw_subsection_type) => raw_subsection_type.into(),
				// todo: be more selective detecting no more subsection
				Err(_) => { break; },
			};

			// deserialize the section size
			VarUint32::deserialize(rdr)?;

			match subsection_type {
				NAME_TYPE_MODULE => {
					if let Some(_) = module_name {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION));
					}
					module_name = Some(ModuleNameSubsection::deserialize(rdr)?);
				},

				NAME_TYPE_FUNCTION => {
					if let Some(_) = function_names {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_FUNCTION));
					}
					function_names = Some(FunctionNameSubsection::deserialize(module, rdr)?);
				},

				NAME_TYPE_LOCAL => {
					if let Some(_) = local_names {
						return Err(Error::DuplicatedNameSubsections(NAME_TYPE_LOCAL));
					}
					local_names = Some(LocalNameSubsection::deserialize(module, rdr)?);
				},

				_ => return Err(Error::UnknownNameSubsectionType(subsection_type))
			};
		}

		Ok(Self {
			module: module_name,
			functions: function_names,
			locals: local_names,
		})
	}
}

impl Serialize for NameSection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		fn serialize_subsection<W: io::Write>(wtr: &mut W, name_type: u8, name_payload: &Vec<u8>) -> Result<(), Error> {
			VarUint7::from(name_type).serialize(wtr)?;
			VarUint32::from(name_payload.len()).serialize(wtr)?;
			wtr.write(name_payload).map_err(Into::into)
		}

		if let Some(module_name_subsection) = self.module {
			let mut buffer = vec![];
			module_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_MODULE, &buffer)?;
		}

		if let Some(function_name_subsection) = self.functions {
			let mut buffer = vec![];
			function_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_FUNCTION, &buffer)?;
		}

		if let Some(local_name_subsection) = self.locals {
			let mut buffer = vec![];
			local_name_subsection.serialize(&mut buffer)?;
			serialize_subsection(wtr, NAME_TYPE_LOCAL, &buffer)?;
		}

		Ok(())
	}
}

/// The name of this module.
#[derive(Clone, Debug, PartialEq)]
pub struct ModuleNameSubsection {
	name: String,
}

impl ModuleNameSubsection {
	/// Create a new module name section with the specified name.
	pub fn new<S: Into<String>>(name: S) -> ModuleNameSubsection {
		ModuleNameSubsection { name: name.into() }
	}

	/// The name of this module.
	pub fn name(&self) -> &str {
		&self.name
	}

	/// The name of this module (mutable).
	pub fn name_mut(&mut self) -> &mut String {
		&mut self.name
	}
}

impl Serialize for ModuleNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.name.serialize(wtr)
	}
}

impl Deserialize for ModuleNameSubsection {
	type Error = Error;

	fn deserialize<R: io::Read>(rdr: &mut R) -> Result<ModuleNameSubsection, Error> {
		let name = String::deserialize(rdr)?;
		Ok(ModuleNameSubsection { name })
	}
}

/// The names of the functions in this module.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FunctionNameSubsection {
	names: NameMap,
}

impl FunctionNameSubsection {
	/// A map from function indices to names.
	pub fn names(&self) -> &NameMap {
		&self.names
	}

	/// A map from function indices to names (mutable).
	pub fn names_mut(&mut self) -> &mut NameMap {
		&mut self.names
	}

	/// Deserialize names, making sure that all names correspond to functions.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<FunctionNameSubsection, Error> {
		let names = IndexMap::deserialize(module.functions_space(), rdr)?;
		Ok(FunctionNameSubsection { names })
	}
}

impl Serialize for FunctionNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.names.serialize(wtr)
	}
}

/// The names of the local variables in this module's functions.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct LocalNameSubsection {
	local_names: IndexMap<NameMap>,
}

impl LocalNameSubsection {
	/// A map from function indices to a map from variables indices to names.
	pub fn local_names(&self) -> &IndexMap<NameMap> {
		&self.local_names
	}

	/// A map from function indices to a map from variables indices to names
	/// (mutable).
	pub fn local_names_mut(&mut self) -> &mut IndexMap<NameMap> {
		&mut self.local_names
	}

	/// Deserialize names, making sure that all names correspond to local
	/// variables.
	pub fn deserialize<R: io::Read>(
		module: &Module,
		rdr: &mut R,
	) -> Result<LocalNameSubsection, Error> {
		let max_entry_space = module.functions_space();

		let max_signature_args = module
			.type_section()
			.map(|ts|
				ts.types()
					.iter()
					.map(|x| { let Type::Function(ref func) = *x; func.params().len() })
					.max()
					.unwrap_or(0))
			.unwrap_or(0);

		let max_locals = module
			.code_section()
			.map(|cs| cs.bodies().iter().map(|f| f.locals().len()).max().unwrap_or(0))
			.unwrap_or(0);

		let max_space = max_signature_args + max_locals;

		let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr);

		let local_names = IndexMap::deserialize_with(
			max_entry_space,
			&deserialize_locals,
			rdr,
		)?;
		Ok(LocalNameSubsection { local_names })
	}}

impl Serialize for LocalNameSubsection {
	type Error = Error;

	fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Error> {
		self.local_names.serialize(wtr)
	}
}

/// A map from indices to names.
pub type NameMap = IndexMap<String>;

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

	// A helper function for the tests. Serialize a section, deserialize it,
	// and make sure it matches the original.
	fn serialize_test(original: NameSection) -> Vec<u8> {
		let mut buffer = vec![];
		original
			.serialize(&mut buffer)
			.expect("serialize error");
		buffer
		// todo: add deserialization to this test
	}

	#[test]
	fn serialize_module_name() {
		let module_name_subsection = ModuleNameSubsection::new("my_mod");
		let original = NameSection::new(Some(module_name_subsection), None, None);
		serialize_test(original.clone());
	}

	#[test]
	fn serialize_function_names() {
		let mut function_name_subsection = FunctionNameSubsection::default();
		function_name_subsection.names_mut().insert(0, "hello_world".to_string());
		let name_section = NameSection::new(None, Some(function_name_subsection), None);
		serialize_test(name_section);
	}

	#[test]
	fn serialize_local_names() {
		let mut local_name_subsection = LocalNameSubsection::default();
		let mut locals = NameMap::default();
		locals.insert(0, "msg".to_string());
		local_name_subsection.local_names_mut().insert(0, locals);

		let name_section = NameSection::new(None, None, Some(local_name_subsection));
		serialize_test(name_section);
	}

	#[test]
	fn serialize_all_subsections() {
		let module_name_subsection = ModuleNameSubsection::new("ModuleNameSubsection");

		let mut function_name_subsection = FunctionNameSubsection::default();
		function_name_subsection.names_mut().insert(0, "foo".to_string());
		function_name_subsection.names_mut().insert(1, "bar".to_string());

		let mut local_name_subsection = LocalNameSubsection::default();
		let mut locals = NameMap::default();
		locals.insert(0, "msg1".to_string());
		locals.insert(1, "msg2".to_string());
		local_name_subsection.local_names_mut().insert(0, locals);

		let name_section = NameSection::new(Some(module_name_subsection), Some(function_name_subsection), Some(local_name_subsection));
		serialize_test(name_section);
	}
}
<|endoftext|>


<commit_before>#[allow(unused)]
pub mod entity;
pub mod http;
pub mod response;
pub mod postparams;

extern crate hyper;
extern crate serde_json;
extern crate urlencoded;

use hyper::client;
use hyper::mime::Mime;
use std;
use std::collections::HashMap;
use std::fmt::Debug;
use std::io::Read;
use std::option::Option;
use std::process::exit;
use std::result::Result;

#[derive(Debug)]
pub struct Api {
    base_uri: &'static str,
    api_key: String,
    login_token: String,
    client: hyper::client::Client,
    user_agent: String,
}

#[allow(unused)]
impl Api {

    /// Create a new api client
    pub fn new(api_key: String) -> Api {
        let crates_version = &std::env::var("CARGO_PKG_VERSION")
            .unwrap_or("unknown".to_string());
        let crates_name = std::env::var("CARGO_PKG_NAME").
            unwrap_or("unknown".to_string());

        let ua = format!("libproxer-rust({}/v{})", crates_name, crates_version);

        Api {
            base_uri:    "http://proxer.me/api/v1/",
            api_key:     api_key,
            login_token: "None".to_string(),
            client:      hyper::client::Client::new(),
            user_agent:  ua,
        }
    }

    pub fn info_get_full_info(self, id: u32) -> Result<client::response::Response, hyper::Error> {
        use api::entity::response::*;
        let url = "info/fullentry";

        response::Response::new::<info::fullinfo::FullInfo>(self.http_req(url))
    }

    fn http_req<T: ToString>(self, url: &str, data: T) -> Result<client::response::Response, hyper::Error> {
        let uri = self.base_uri.to_string()+url;
        let hyper_url = hyper::Url::parse(&uri).unwrap();

        let mut headers = hyper::header::Headers::new();
        header! {(ProxerApiKeyHeader, "proxer-api-key") => [String]}
        header! {(UserAgent, "User-Agent") => [String]}
        headers.set(ProxerApiKeyHeader(self.api_key));
        headers.set(UserAgent(self.user_agent));
        headers.set(hyper::header::ContentType::form_url_encoded());

        self.client
            .post(hyper_url)
            .headers(headers)
            .body(&data.to_string())
            .send()
    }

    pub fn read_json(json: String) -> std::result::Result<serde_json::Value, serde_json::Error> {
        serde_json::from_str(&json)
    }
}

fn hashmap_to_encoded_url(params: HashMap<String, String>) -> String{
    "foobar".to_string()
}
<commit_msg>implement request parameters<commit_after>#[allow(unused)]
pub mod entity;
pub mod http;
pub mod response;
pub mod postparams;

extern crate hyper;
extern crate serde_json;
extern crate urlencoded;

use hyper::client;
use hyper::mime::Mime;
use std;
use std::collections::HashMap;
use std::fmt::Debug;
use std::io::Read;
use std::option::Option;
use std::process::exit;
use std::result::Result;

#[derive(Debug)]
pub struct Api {
    base_uri: &'static str,
    api_key: String,
    login_token: String,
    client: hyper::client::Client,
    user_agent: String,
}

#[allow(unused)]
impl Api {

    /// Create a new api client
    pub fn new(api_key: String) -> Api {
        let crates_version = &std::env::var("CARGO_PKG_VERSION")
            .unwrap_or("unknown".to_string());
        let crates_name = std::env::var("CARGO_PKG_NAME").
            unwrap_or("unknown".to_string());

        let ua = format!("libproxer-rust({}/v{})", crates_name, crates_version);

        Api {
            base_uri:    "http://proxer.me/api/v1/",
            api_key:     api_key,
            login_token: "None".to_string(),
            client:      hyper::client::Client::new(),
            user_agent:  ua,
        }
    }

    pub fn info_get_full_info(self, id: u32) -> Result<client::response::Response, hyper::Error> {
        use api::entity::response::*;
        let url = "info/fullentry";

        let mut post = postparams::Postparams::new();

        post.add("id", id);

        response::Response::new::<info::fullinfo::FullInfo>(self.http_req(url, post))
    }

    fn http_req<T: ToString>(self, url: &str, data: T) -> Result<client::response::Response, hyper::Error> {
        let uri = self.base_uri.to_string()+url;
        let hyper_url = hyper::Url::parse(&uri).unwrap();

        let mut headers = hyper::header::Headers::new();
        header! {(ProxerApiKeyHeader, "proxer-api-key") => [String]}
        header! {(UserAgent, "User-Agent") => [String]}
        headers.set(ProxerApiKeyHeader(self.api_key));
        headers.set(UserAgent(self.user_agent));
        headers.set(hyper::header::ContentType::form_url_encoded());

        self.client
            .post(hyper_url)
            .headers(headers)
            .body(&data.to_string())
            .send()
    }

    pub fn read_json(json: String) -> std::result::Result<serde_json::Value, serde_json::Error> {
        serde_json::from_str(&json)
    }
}

fn hashmap_to_encoded_url(params: HashMap<String, String>) -> String{
    "foobar".to_string()
}
<|endoftext|>


<commit_before>use std::fs::File;

use super::Pio;

use super::*;

pub(crate) trait LogReader {
    fn read_segment_header(&self, id: LogId) -> Result<SegmentHeader>;

    fn read_message(
        &self,
        lid: LogId,
        expected_lsn: Lsn,
        config: &Config,
    ) -> Result<LogRead>;
}

impl LogReader for File {
    fn read_segment_header(&self, lid: LogId) -> Result<SegmentHeader> {
        trace!("reading segment header at {}", lid);

        let mut seg_header_buf = [0u8; SEG_HEADER_LEN];
        self.pread_exact(&mut seg_header_buf, lid)?;
        let mut segment_header = SegmentHeader::from(seg_header_buf);

        if segment_header.lsn < Lsn::try_from(lid).unwrap() {
            debug!(
                "segment had lsn {} but we expected something \
                 greater, as the base lid is {}",
                segment_header.lsn, lid
            );
            segment_header.ok = false;
        }

        Ok(segment_header)
    }

    /// read a buffer from the disk
    fn read_message(
        &self,
        lid: LogId,
        expected_lsn: Lsn,
        config: &Config,
    ) -> Result<LogRead> {
        let mut msg_header_buf = [0u8; MSG_HEADER_LEN];

        self.pread_exact(&mut msg_header_buf, lid)?;
        let header: MessageHeader = msg_header_buf.into();

        // we set the crc bytes to 0 because we will
        // calculate the crc32 over all bytes other
        // than the crc itself, including the bytes
        // in the header.
        unsafe {
            std::ptr::write_bytes(
                msg_header_buf
                    .as_mut_ptr()
                    .add(MSG_HEADER_LEN - std::mem::size_of::<u32>()),
                0xFF,
                std::mem::size_of::<u32>(),
            );
        }

        let _measure = Measure::new(&M.read);
        let segment_len = config.io_buf_size;
        let seg_start = lid / segment_len as LogId * segment_len as LogId;
        trace!(
            "reading message from segment: {} at lid: {}",
            seg_start,
            lid
        );
        assert!(seg_start + SEG_HEADER_LEN as LogId <= lid);

        let ceiling = seg_start + segment_len as LogId;

        assert!(lid + MSG_HEADER_LEN as LogId <= ceiling);

        if header.lsn % segment_len as Lsn != lid as Lsn % segment_len as Lsn {
            let _hb: [u8; MSG_HEADER_LEN] = header.into();
            // our message lsn was not aligned to our segment offset
            trace!(
                "read a message whose header lsn \
                 is not aligned to its position \
                 within its segment. header: {:?} \
                 expected: relative offset {} bytes: {:?}",
                header,
                lid % segment_len as LogId,
                _hb
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        if header.lsn != expected_lsn {
            debug!(
                "header {:?} does not contain expected lsn {}",
                header, expected_lsn
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        let max_possible_len =
            assert_usize(ceiling - lid - MSG_HEADER_LEN as LogId);

        if usize::try_from(header.len).unwrap() > max_possible_len {
            trace!(
                "read a corrupted message with impossibly long length {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        if header.kind == MessageKind::Corrupted {
            trace!(
                "read a corrupted message with Corrupted MessageKind: {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        // perform crc check on everything that isn't Corrupted
        let mut buf = Vec::with_capacity(usize::try_from(header.len).unwrap());
        unsafe {
            buf.set_len(usize::try_from(header.len).unwrap());
        }
        self.pread_exact(&mut buf, lid + MSG_HEADER_LEN as LogId)?;

        // calculate the CRC32, calculating the hash on the
        // header afterwards
        let mut hasher = crc32fast::Hasher::new();
        hasher.update(&buf);
        hasher.update(&msg_header_buf);

        let crc32 = hasher.finalize();

        if crc32 != header.crc32 {
            trace!(
                "read a message with a bad checksum with header {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        match header.kind {
            MessageKind::Cancelled => {
                trace!("read failed of len {}", header.len);
                Ok(LogRead::Failed(header.lsn, header.len))
            }
            MessageKind::Pad => {
                trace!("read pad at lsn {}", header.lsn);
                Ok(LogRead::Pad(header.lsn))
            }
            MessageKind::BlobAppend
            | MessageKind::BlobReplace
            | MessageKind::BlobMeta
            | MessageKind::BlobConfig => {
                let id = arr_to_u64(&buf) as Lsn;

                match read_blob(id, config) {
                    Ok((kind, buf)) => {
                        assert_eq!(header.kind, kind);
                        trace!(
                            "read a successful blob message for Blob({}, {})",
                            header.lsn,
                            id,
                        );

                        Ok(LogRead::Blob(header, buf, id))
                    }
                    Err(Error::Io(ref e))
                        if e.kind() == std::io::ErrorKind::NotFound =>
                    {
                        debug!(
                            "underlying blob file not found for Blob({}, {})",
                            header.lsn, id,
                        );
                        Ok(LogRead::DanglingBlob(header, id))
                    }
                    Err(other_e) => {
                        debug!("failed to read blob: {:?}", other_e);
                        Err(other_e)
                    }
                }
            }
            MessageKind::InlineAppend
            | MessageKind::InlineReplace
            | MessageKind::InlineMeta
            | MessageKind::InlineConfig
            | MessageKind::Free
            | MessageKind::Counter => {
                trace!("read a successful inline message");
                let buf = if config.use_compression {
                    maybe_decompress(buf)?
                } else {
                    buf
                };

                Ok(LogRead::Inline(header, buf, header.len))
            }
            MessageKind::BatchManifest => {
                assert_eq!(buf.len(), std::mem::size_of::<Lsn>());
                let max_lsn = Lsn::try_from(arr_to_u64(&buf)).unwrap();
                Ok(LogRead::BatchManifest(max_lsn))
            }
            MessageKind::Corrupted => panic!(
                "corrupted should have been handled \
                 before reading message length above"
            ),
        }
    }
}
<commit_msg>Don't perform validation of lsn being >= lid on the read-side, as it can legitimately drift in the presence of deferred removals<commit_after>use std::fs::File;

use super::Pio;

use super::*;

pub(crate) trait LogReader {
    fn read_segment_header(&self, id: LogId) -> Result<SegmentHeader>;

    fn read_message(
        &self,
        lid: LogId,
        expected_lsn: Lsn,
        config: &Config,
    ) -> Result<LogRead>;
}

impl LogReader for File {
    fn read_segment_header(&self, lid: LogId) -> Result<SegmentHeader> {
        trace!("reading segment header at {}", lid);

        let mut seg_header_buf = [0u8; SEG_HEADER_LEN];
        self.pread_exact(&mut seg_header_buf, lid)?;
        let segment_header = SegmentHeader::from(seg_header_buf);

        if segment_header.lsn < Lsn::try_from(lid).unwrap() {
            debug!(
                "segment had lsn {} but we expected something \
                 greater, as the base lid is {}",
                segment_header.lsn, lid
            );
        }

        Ok(segment_header)
    }

    /// read a buffer from the disk
    fn read_message(
        &self,
        lid: LogId,
        expected_lsn: Lsn,
        config: &Config,
    ) -> Result<LogRead> {
        let mut msg_header_buf = [0u8; MSG_HEADER_LEN];

        self.pread_exact(&mut msg_header_buf, lid)?;
        let header: MessageHeader = msg_header_buf.into();

        // we set the crc bytes to 0 because we will
        // calculate the crc32 over all bytes other
        // than the crc itself, including the bytes
        // in the header.
        unsafe {
            std::ptr::write_bytes(
                msg_header_buf
                    .as_mut_ptr()
                    .add(MSG_HEADER_LEN - std::mem::size_of::<u32>()),
                0xFF,
                std::mem::size_of::<u32>(),
            );
        }

        let _measure = Measure::new(&M.read);
        let segment_len = config.io_buf_size;
        let seg_start = lid / segment_len as LogId * segment_len as LogId;
        trace!(
            "reading message from segment: {} at lid: {}",
            seg_start,
            lid
        );
        assert!(seg_start + SEG_HEADER_LEN as LogId <= lid);

        let ceiling = seg_start + segment_len as LogId;

        assert!(lid + MSG_HEADER_LEN as LogId <= ceiling);

        if header.lsn % segment_len as Lsn != lid as Lsn % segment_len as Lsn {
            let _hb: [u8; MSG_HEADER_LEN] = header.into();
            // our message lsn was not aligned to our segment offset
            trace!(
                "read a message whose header lsn \
                 is not aligned to its position \
                 within its segment. header: {:?} \
                 expected: relative offset {} bytes: {:?}",
                header,
                lid % segment_len as LogId,
                _hb
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        if header.lsn != expected_lsn {
            debug!(
                "header {:?} does not contain expected lsn {}",
                header, expected_lsn
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        let max_possible_len =
            assert_usize(ceiling - lid - MSG_HEADER_LEN as LogId);

        if usize::try_from(header.len).unwrap() > max_possible_len {
            trace!(
                "read a corrupted message with impossibly long length {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        if header.kind == MessageKind::Corrupted {
            trace!(
                "read a corrupted message with Corrupted MessageKind: {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        // perform crc check on everything that isn't Corrupted
        let mut buf = Vec::with_capacity(usize::try_from(header.len).unwrap());
        unsafe {
            buf.set_len(usize::try_from(header.len).unwrap());
        }
        self.pread_exact(&mut buf, lid + MSG_HEADER_LEN as LogId)?;

        // calculate the CRC32, calculating the hash on the
        // header afterwards
        let mut hasher = crc32fast::Hasher::new();
        hasher.update(&buf);
        hasher.update(&msg_header_buf);

        let crc32 = hasher.finalize();

        if crc32 != header.crc32 {
            trace!(
                "read a message with a bad checksum with header {:?}",
                header
            );
            return Ok(LogRead::Corrupted(header.len));
        }

        match header.kind {
            MessageKind::Cancelled => {
                trace!("read failed of len {}", header.len);
                Ok(LogRead::Failed(header.lsn, header.len))
            }
            MessageKind::Pad => {
                trace!("read pad at lsn {}", header.lsn);
                Ok(LogRead::Pad(header.lsn))
            }
            MessageKind::BlobAppend
            | MessageKind::BlobReplace
            | MessageKind::BlobMeta
            | MessageKind::BlobConfig => {
                let id = arr_to_u64(&buf) as Lsn;

                match read_blob(id, config) {
                    Ok((kind, buf)) => {
                        assert_eq!(header.kind, kind);
                        trace!(
                            "read a successful blob message for Blob({}, {})",
                            header.lsn,
                            id,
                        );

                        Ok(LogRead::Blob(header, buf, id))
                    }
                    Err(Error::Io(ref e))
                        if e.kind() == std::io::ErrorKind::NotFound =>
                    {
                        debug!(
                            "underlying blob file not found for Blob({}, {})",
                            header.lsn, id,
                        );
                        Ok(LogRead::DanglingBlob(header, id))
                    }
                    Err(other_e) => {
                        debug!("failed to read blob: {:?}", other_e);
                        Err(other_e)
                    }
                }
            }
            MessageKind::InlineAppend
            | MessageKind::InlineReplace
            | MessageKind::InlineMeta
            | MessageKind::InlineConfig
            | MessageKind::Free
            | MessageKind::Counter => {
                trace!("read a successful inline message");
                let buf = if config.use_compression {
                    maybe_decompress(buf)?
                } else {
                    buf
                };

                Ok(LogRead::Inline(header, buf, header.len))
            }
            MessageKind::BatchManifest => {
                assert_eq!(buf.len(), std::mem::size_of::<Lsn>());
                let max_lsn = Lsn::try_from(arr_to_u64(&buf)).unwrap();
                Ok(LogRead::BatchManifest(max_lsn))
            }
            MessageKind::Corrupted => panic!(
                "corrupted should have been handled \
                 before reading message length above"
            ),
        }
    }
}
<|endoftext|>


<commit_before>use std::{
    convert::TryInto,
    time::{Duration, SystemTime, UNIX_EPOCH},
};

use js_int::{uint, UInt};
use serde::{Deserialize, Serialize};

/// A timestamp represented as the number of milliseconds since the unix epoch.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
#[serde(transparent)]
pub struct MilliSecondsSinceUnixEpoch(pub UInt);

impl MilliSecondsSinceUnixEpoch {
    /// Creates a new `MilliSecondsSinceUnixEpoch` from the given `SystemTime`, if it is not before
    /// the unix epoch, or too large to be represented.
    pub fn from_system_time(time: SystemTime) -> Option<Self> {
        let duration = time.duration_since(UNIX_EPOCH).ok()?;
        let millis = duration.as_millis().try_into().ok()?;
        Some(Self(millis))
    }

    /// The current milliseconds since the unix epoch.
    pub fn now() -> Self {
        Self::from_system_time(SystemTime::now()).unwrap()
    }

    /// Creates a new `SystemTime` from `self`, if it can be represented.
    pub fn to_system_time(self) -> Option<SystemTime> {
        UNIX_EPOCH.checked_add(Duration::from_millis(self.0.into()))
    }

    /// Get the time since the unix epoch in milliseconds.
    pub fn get(&self) -> UInt {
        self.0
    }

    /// Get time since the unix epoch in seconds.
    pub fn as_secs(&self) -> UInt {
        self.0 / uint!(1000)
    }
}

/// A timestamp represented as the number of seconds since the unix epoch.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
#[serde(transparent)]
pub struct SecondsSinceUnixEpoch(pub UInt);

impl SecondsSinceUnixEpoch {
    /// Creates a new `MilliSecondsSinceUnixEpoch` from the given `SystemTime`, if it is not before
    /// the unix epoch, or too large to be represented.
    pub fn from_system_time(time: SystemTime) -> Option<Self> {
        let duration = time.duration_since(UNIX_EPOCH).ok()?;
        let millis = duration.as_secs().try_into().ok()?;
        Some(Self(millis))
    }

    /// Creates a new `SystemTime` from `self`, if it can be represented.
    pub fn to_system_time(self) -> Option<SystemTime> {
        UNIX_EPOCH.checked_add(Duration::from_secs(self.0.into()))
    }

    /// Get time since the unix epoch in seconds.
    pub fn get(&self) -> UInt {
        self.0
    }
}

#[cfg(test)]
mod tests {
    use std::time::{Duration, UNIX_EPOCH};

    use js_int::uint;
    use matches::assert_matches;
    use serde::{Deserialize, Serialize};
    use serde_json::json;

    use super::{MilliSecondsSinceUnixEpoch, SecondsSinceUnixEpoch};

    #[derive(Clone, Debug, Deserialize, Serialize)]
    struct SystemTimeTest {
        millis: MilliSecondsSinceUnixEpoch,
        secs: SecondsSinceUnixEpoch,
    }

    #[test]
    fn deserialize() {
        let json = json!({ "millis": 3000, "secs": 60 });

        assert_matches!(
            serde_json::from_value::<SystemTimeTest>(json),
            Ok(SystemTimeTest { millis, secs })
            if millis.to_system_time() == Some(UNIX_EPOCH + Duration::from_millis(3000))
                && secs.to_system_time() == Some(UNIX_EPOCH + Duration::from_secs(60))
        );
    }

    #[test]
    fn serialize() {
        let request = SystemTimeTest {
            millis: MilliSecondsSinceUnixEpoch::from_system_time(UNIX_EPOCH + Duration::new(2, 0))
                .unwrap(),
            secs: SecondsSinceUnixEpoch(uint!(0)),
        };
        assert_matches!(
            serde_json::to_value(&request),
            Ok(value) if value == json!({ "millis": 2000, "secs": 0 })
        );
    }
}
<commit_msg>common: Improve docs for MilliSecondsSinceUnixEpoch::now<commit_after>use std::{
    convert::TryInto,
    time::{Duration, SystemTime, UNIX_EPOCH},
};

use js_int::{uint, UInt};
use serde::{Deserialize, Serialize};

/// A timestamp represented as the number of milliseconds since the unix epoch.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
#[serde(transparent)]
pub struct MilliSecondsSinceUnixEpoch(pub UInt);

impl MilliSecondsSinceUnixEpoch {
    /// Creates a new `MilliSecondsSinceUnixEpoch` from the given `SystemTime`, if it is not before
    /// the unix epoch, or too large to be represented.
    pub fn from_system_time(time: SystemTime) -> Option<Self> {
        let duration = time.duration_since(UNIX_EPOCH).ok()?;
        let millis = duration.as_millis().try_into().ok()?;
        Some(Self(millis))
    }

    /// The current system time in milliseconds since the unix epoch.
    pub fn now() -> Self {
        Self::from_system_time(SystemTime::now()).unwrap()
    }

    /// Creates a new `SystemTime` from `self`, if it can be represented.
    pub fn to_system_time(self) -> Option<SystemTime> {
        UNIX_EPOCH.checked_add(Duration::from_millis(self.0.into()))
    }

    /// Get the time since the unix epoch in milliseconds.
    pub fn get(&self) -> UInt {
        self.0
    }

    /// Get time since the unix epoch in seconds.
    pub fn as_secs(&self) -> UInt {
        self.0 / uint!(1000)
    }
}

/// A timestamp represented as the number of seconds since the unix epoch.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
#[serde(transparent)]
pub struct SecondsSinceUnixEpoch(pub UInt);

impl SecondsSinceUnixEpoch {
    /// Creates a new `MilliSecondsSinceUnixEpoch` from the given `SystemTime`, if it is not before
    /// the unix epoch, or too large to be represented.
    pub fn from_system_time(time: SystemTime) -> Option<Self> {
        let duration = time.duration_since(UNIX_EPOCH).ok()?;
        let millis = duration.as_secs().try_into().ok()?;
        Some(Self(millis))
    }

    /// Creates a new `SystemTime` from `self`, if it can be represented.
    pub fn to_system_time(self) -> Option<SystemTime> {
        UNIX_EPOCH.checked_add(Duration::from_secs(self.0.into()))
    }

    /// Get time since the unix epoch in seconds.
    pub fn get(&self) -> UInt {
        self.0
    }
}

#[cfg(test)]
mod tests {
    use std::time::{Duration, UNIX_EPOCH};

    use js_int::uint;
    use matches::assert_matches;
    use serde::{Deserialize, Serialize};
    use serde_json::json;

    use super::{MilliSecondsSinceUnixEpoch, SecondsSinceUnixEpoch};

    #[derive(Clone, Debug, Deserialize, Serialize)]
    struct SystemTimeTest {
        millis: MilliSecondsSinceUnixEpoch,
        secs: SecondsSinceUnixEpoch,
    }

    #[test]
    fn deserialize() {
        let json = json!({ "millis": 3000, "secs": 60 });

        assert_matches!(
            serde_json::from_value::<SystemTimeTest>(json),
            Ok(SystemTimeTest { millis, secs })
            if millis.to_system_time() == Some(UNIX_EPOCH + Duration::from_millis(3000))
                && secs.to_system_time() == Some(UNIX_EPOCH + Duration::from_secs(60))
        );
    }

    #[test]
    fn serialize() {
        let request = SystemTimeTest {
            millis: MilliSecondsSinceUnixEpoch::from_system_time(UNIX_EPOCH + Duration::new(2, 0))
                .unwrap(),
            secs: SecondsSinceUnixEpoch(uint!(0)),
        };
        assert_matches!(
            serde_json::to_value(&request),
            Ok(value) if value == json!({ "millis": 2000, "secs": 0 })
        );
    }
}
<|endoftext|>


<commit_before>use crate::utils;

use clap::{arg, error::ErrorKind, Arg, ArgGroup, Command};

static REQ_GROUP_USAGE: &str = "error: The following required arguments were not provided:
    <base|--delete>

USAGE:
    clap-test <base|--delete>

For more information try --help
";

static REQ_GROUP_CONFLICT_USAGE: &str =
    "error: The argument '--delete' cannot be used with '<base>'

USAGE:
    clap-test <base|--delete>

For more information try --help
";

static REQ_GROUP_CONFLICT_ONLY_OPTIONS: &str =
    "error: The argument '--delete' cannot be used with '--all'

USAGE:
    clap-test <--all|--delete>

For more information try --help
";

#[test]
fn required_group_missing_arg() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!( -c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag", "color"]).required(true))
        .try_get_matches_from(vec![""]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group 'req' contains non-existent argument"]
fn non_existing_arg() {
    let _ = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flg", "color"]).required(true))
        .try_get_matches_from(vec![""]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name must be unique\n\n\t'req' is already in use"]
fn unique_group_name() {
    let _ = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag"]).required(true))
        .group(ArgGroup::new("req").args(&["color"]).required(true))
        .try_get_matches_from(vec![""]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name '' must not conflict with argument name"]
fn groups_new_of_arg_name() {
    let _ = Command::new("group")
        .arg(Arg::new("a").long("a").group("a"))
        .try_get_matches_from(vec!["", "--a"]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name 'a' must not conflict with argument name"]
fn arg_group_new_of_arg_name() {
    let _ = Command::new("group")
        .arg(Arg::new("a").long("a").group("a"))
        .group(ArgGroup::new("a"))
        .try_get_matches_from(vec!["", "--a"]);
}

#[test]
fn group_single_value() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-c", "blue"]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert_eq!(m.value_of("grp").unwrap(), "blue");
}

#[test]
fn group_single_flag() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-f"]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert!(m.value_of("grp").is_none());
}

#[test]
fn group_empty() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec![""]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(!m.is_present("grp"));
    assert!(m.value_of("grp").is_none());
}

#[test]
fn group_reqired_flags_empty() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some option"))
        .group(ArgGroup::new("grp").required(true).args(&["flag", "color"]))
        .try_get_matches_from(vec![""]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[test]
fn group_multi_value_single_arg() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color <color> "some option").multiple_values(true))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
    assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert_eq!(
        &*m.values_of("grp").unwrap().collect::<Vec<_>>(),
        &["blue", "red", "green"]
    );
}

#[test]
fn empty_group() {
    let r = Command::new("empty_group")
        .arg(arg!(-f --flag "some flag"))
        .group(ArgGroup::new("vers").required(true))
        .try_get_matches_from(vec!["empty_prog"]);
    assert!(r.is_err());
    let err = r.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[test]
fn req_group_usage_string() {
    let cmd = Command::new("req_group")
        .arg(arg!([base] "Base commit"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("base_or_delete")
                .args(&["base", "delete"])
                .required(true),
        );

    assert!(utils::compare_output(
        cmd,
        "clap-test",
        REQ_GROUP_USAGE,
        true
    ));
}

#[test]
fn req_group_with_conflict_usage_string() {
    let cmd = Command::new("req_group")
        .arg(arg!([base] "Base commit").conflicts_with("delete"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("base_or_delete")
                .args(&["base", "delete"])
                .required(true),
        );

    assert!(utils::compare_output(
        cmd,
        "clap-test --delete base",
        REQ_GROUP_CONFLICT_USAGE,
        true
    ));
}

#[test]
fn req_group_with_conflict_usage_string_only_options() {
    let cmd = Command::new("req_group")
        .arg(arg!(-a --all "All").conflicts_with("delete"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("all_or_delete")
                .args(&["all", "delete"])
                .required(true),
        );
    assert!(utils::compare_output(
        cmd,
        "clap-test --delete --all",
        REQ_GROUP_CONFLICT_ONLY_OPTIONS,
        true
    ));
}

#[test]
fn required_group_multiple_args() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(
            ArgGroup::new("req")
                .args(&["flag", "color"])
                .required(true)
                .multiple(true),
        )
        .try_get_matches_from(vec!["group", "-f", "-c"]);
    assert!(result.is_ok(), "{}", result.unwrap_err());
    let m = result.unwrap();
    assert!(m.is_present("flag"));
    assert!(m.is_present("color"));
}

#[test]
fn group_multiple_args_error() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag", "color"]))
        .try_get_matches_from(vec!["group", "-f", "-c"]);
    assert!(result.is_err());
    let err = result.unwrap_err();
    assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
}

#[test]
fn group_usage_use_val_name() {
    static GROUP_USAGE_USE_VAL_NAME: &str = "prog

USAGE:
    prog

ARGS:

OPTIONS:
    -h, --help    Print help information
";
    let cmd = Command::new("prog")
        .arg(Arg::new("a").value_name("A"))
        .group(ArgGroup::new("group").arg("a").required(true));
    assert!(utils::compare_output(
        cmd,
        "prog --help",
        GROUP_USAGE_USE_VAL_NAME,
        false,
    ));
}

#[test]
fn group_acts_like_arg() {
    let result = Command::new("prog")
        .arg(Arg::new("debug").long("debug").group("mode"))
        .arg(Arg::new("verbose").long("verbose").group("mode"))
        .try_get_matches_from(vec!["prog", "--debug"]);

    assert!(result.is_ok(), "{}", result.unwrap_err());
    let m = result.unwrap();
    assert!(m.is_present("mode"));
}

/* This is used to be fixed in a hack, we need to find a better way to fix it.
#[test]
fn issue_1794() {
    let cmd = clap::Command::new("hello")
        .bin_name("deno")
        .arg(Arg::new("option1").long("option1").takes_value(false))
        .arg(Arg::new("pos1").takes_value(true))
        .arg(Arg::new("pos2").takes_value(true))
        .group(
            ArgGroup::new("arg1")
                .args(&["pos1", "option1"])
                .required(true),
        );

    let m = cmd.clone().try_get_matches_from(&["cmd", "pos1", "pos2"]).unwrap();
    assert_eq!(m.value_of("pos1"), Some("pos1"));
    assert_eq!(m.value_of("pos2"), Some("pos2"));
    assert!(!m.is_present("option1"));

    let m = cmd
        .clone()
        .try_get_matches_from(&["cmd", "--option1", "positional"]).unwrap();
    assert_eq!(m.value_of("pos1"), None);
    assert_eq!(m.value_of("pos2"), Some("positional"));
    assert!(m.is_present("option1"));
}
*/
<commit_msg>test(group): Verify overrides required<commit_after>use crate::utils;

use clap::{arg, error::ErrorKind, Arg, ArgGroup, Command};

static REQ_GROUP_USAGE: &str = "error: The following required arguments were not provided:
    <base|--delete>

USAGE:
    clap-test <base|--delete>

For more information try --help
";

static REQ_GROUP_CONFLICT_USAGE: &str =
    "error: The argument '--delete' cannot be used with '<base>'

USAGE:
    clap-test <base|--delete>

For more information try --help
";

static REQ_GROUP_CONFLICT_ONLY_OPTIONS: &str =
    "error: The argument '--delete' cannot be used with '--all'

USAGE:
    clap-test <--all|--delete>

For more information try --help
";

#[test]
fn required_group_missing_arg() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!( -c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag", "color"]).required(true))
        .try_get_matches_from(vec![""]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group 'req' contains non-existent argument"]
fn non_existing_arg() {
    let _ = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flg", "color"]).required(true))
        .try_get_matches_from(vec![""]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name must be unique\n\n\t'req' is already in use"]
fn unique_group_name() {
    let _ = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag"]).required(true))
        .group(ArgGroup::new("req").args(&["color"]).required(true))
        .try_get_matches_from(vec![""]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name '' must not conflict with argument name"]
fn groups_new_of_arg_name() {
    let _ = Command::new("group")
        .arg(Arg::new("a").long("a").group("a"))
        .try_get_matches_from(vec!["", "--a"]);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument group name 'a' must not conflict with argument name"]
fn arg_group_new_of_arg_name() {
    let _ = Command::new("group")
        .arg(Arg::new("a").long("a").group("a"))
        .group(ArgGroup::new("a"))
        .try_get_matches_from(vec!["", "--a"]);
}

#[test]
fn group_single_value() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-c", "blue"]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert_eq!(m.value_of("grp").unwrap(), "blue");
}

#[test]
fn group_single_flag() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-f"]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert!(m.value_of("grp").is_none());
}

#[test]
fn group_empty() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color [color] "some option"))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec![""]);
    assert!(res.is_ok(), "{}", res.unwrap_err());

    let m = res.unwrap();
    assert!(!m.is_present("grp"));
    assert!(m.value_of("grp").is_none());
}

#[test]
fn group_reqired_flags_empty() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some option"))
        .group(ArgGroup::new("grp").required(true).args(&["flag", "color"]))
        .try_get_matches_from(vec![""]);
    assert!(result.is_err());
    let err = result.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[test]
fn group_multi_value_single_arg() {
    let res = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color <color> "some option").multiple_values(true))
        .group(ArgGroup::new("grp").args(&["flag", "color"]))
        .try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
    assert!(res.is_ok(), "{:?}", res.unwrap_err().kind());

    let m = res.unwrap();
    assert!(m.is_present("grp"));
    assert_eq!(
        &*m.values_of("grp").unwrap().collect::<Vec<_>>(),
        &["blue", "red", "green"]
    );
}

#[test]
fn empty_group() {
    let r = Command::new("empty_group")
        .arg(arg!(-f --flag "some flag"))
        .group(ArgGroup::new("vers").required(true))
        .try_get_matches_from(vec!["empty_prog"]);
    assert!(r.is_err());
    let err = r.err().unwrap();
    assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument);
}

#[test]
fn req_group_usage_string() {
    let cmd = Command::new("req_group")
        .arg(arg!([base] "Base commit"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("base_or_delete")
                .args(&["base", "delete"])
                .required(true),
        );

    assert!(utils::compare_output(
        cmd,
        "clap-test",
        REQ_GROUP_USAGE,
        true
    ));
}

#[test]
fn req_group_with_conflict_usage_string() {
    let cmd = Command::new("req_group")
        .arg(arg!([base] "Base commit").conflicts_with("delete"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("base_or_delete")
                .args(&["base", "delete"])
                .required(true),
        );

    assert!(utils::compare_output(
        cmd,
        "clap-test --delete base",
        REQ_GROUP_CONFLICT_USAGE,
        true
    ));
}

#[test]
fn req_group_with_conflict_usage_string_only_options() {
    let cmd = Command::new("req_group")
        .arg(arg!(-a --all "All").conflicts_with("delete"))
        .arg(arg!(
            -d --delete "Remove the base commit information"
        ))
        .group(
            ArgGroup::new("all_or_delete")
                .args(&["all", "delete"])
                .required(true),
        );
    assert!(utils::compare_output(
        cmd,
        "clap-test --delete --all",
        REQ_GROUP_CONFLICT_ONLY_OPTIONS,
        true
    ));
}

#[test]
fn required_group_multiple_args() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(
            ArgGroup::new("req")
                .args(&["flag", "color"])
                .required(true)
                .multiple(true),
        )
        .try_get_matches_from(vec!["group", "-f", "-c"]);
    assert!(result.is_ok(), "{}", result.unwrap_err());
    let m = result.unwrap();
    assert!(m.is_present("flag"));
    assert!(m.is_present("color"));
}

#[test]
fn group_multiple_args_error() {
    let result = Command::new("group")
        .arg(arg!(-f --flag "some flag"))
        .arg(arg!(-c --color "some other flag"))
        .group(ArgGroup::new("req").args(&["flag", "color"]))
        .try_get_matches_from(vec!["group", "-f", "-c"]);
    assert!(result.is_err());
    let err = result.unwrap_err();
    assert_eq!(err.kind(), ErrorKind::ArgumentConflict);
}

#[test]
fn group_overrides_required() {
    let command = Command::new("group")
        .arg(arg!(--foo <FOO>))
        .arg(arg!(--bar <BAR>))
        .group(ArgGroup::new("group").args(&["foo", "bar"]).required(true));
    let result = command.try_get_matches_from(vec!["group", "--foo", "value"]);
    assert!(result.is_ok(), "{}", result.unwrap_err());
    let m = result.unwrap();
    assert!(m.is_present("foo"));
    assert!(!m.is_present("bar"));
}

#[test]
fn group_usage_use_val_name() {
    static GROUP_USAGE_USE_VAL_NAME: &str = "prog

USAGE:
    prog

ARGS:

OPTIONS:
    -h, --help    Print help information
";
    let cmd = Command::new("prog")
        .arg(Arg::new("a").value_name("A"))
        .group(ArgGroup::new("group").arg("a").required(true));
    assert!(utils::compare_output(
        cmd,
        "prog --help",
        GROUP_USAGE_USE_VAL_NAME,
        false,
    ));
}

#[test]
fn group_acts_like_arg() {
    let result = Command::new("prog")
        .arg(Arg::new("debug").long("debug").group("mode"))
        .arg(Arg::new("verbose").long("verbose").group("mode"))
        .try_get_matches_from(vec!["prog", "--debug"]);

    assert!(result.is_ok(), "{}", result.unwrap_err());
    let m = result.unwrap();
    assert!(m.is_present("mode"));
}

/* This is used to be fixed in a hack, we need to find a better way to fix it.
#[test]
fn issue_1794() {
    let cmd = clap::Command::new("hello")
        .bin_name("deno")
        .arg(Arg::new("option1").long("option1").takes_value(false))
        .arg(Arg::new("pos1").takes_value(true))
        .arg(Arg::new("pos2").takes_value(true))
        .group(
            ArgGroup::new("arg1")
                .args(&["pos1", "option1"])
                .required(true),
        );

    let m = cmd.clone().try_get_matches_from(&["cmd", "pos1", "pos2"]).unwrap();
    assert_eq!(m.value_of("pos1"), Some("pos1"));
    assert_eq!(m.value_of("pos2"), Some("pos2"));
    assert!(!m.is_present("option1"));

    let m = cmd
        .clone()
        .try_get_matches_from(&["cmd", "--option1", "positional"]).unwrap();
    assert_eq!(m.value_of("pos1"), None);
    assert_eq!(m.value_of("pos2"), Some("positional"));
    assert!(m.is_present("option1"));
}
*/
<|endoftext|>