<commit_before>#![allow(clippy::new_without_default_derive)] // https://github.com/rust-lang/rust-clippy/issues/3632

use serde_json;
use std::collections::HashMap;
use std::panic::RefUnwindSafe;

use super::Job;
use crate::util::CargoResult;

#[doc(hidden)]
pub type PerformFn<Env> =
    Box<dyn Fn(serde_json::Value, &Env) -> CargoResult<()> + RefUnwindSafe + Send + Sync>;

#[derive(Default)]
#[allow(missing_debug_implementations)] // Can't derive debug
/// A registry of background jobs, used to map job types to concrege perform
/// functions at runtime.
pub struct Registry<Env> {
    job_types: HashMap<&'static str, PerformFn<Env>>,
}

impl<Env> Registry<Env> {
    /// Create a new, empty registry
    pub fn new() -> Self {
        Registry {
            job_types: Default::default(),
        }
    }

    /// Get the perform function for a given job type
    pub fn get(&self, job_type: &str) -> Option<&PerformFn<Env>> {
        self.job_types.get(job_type)
    }

    /// Register a new background job. This will override any existing
    /// registries with the same `JOB_TYPE`, if one exists.
    pub fn register<T: Job<Environment = Env>>(&mut self) {
        self.job_types.insert(
            T::JOB_TYPE,
            Box::new(|data, env| {
                let data = serde_json::from_value(data)?;
                T::perform(data, env)
            }),
        );
    }
}
<commit_msg>Use renamed clippy lint<commit_after>#![allow(clippy::new_without_default)] // https://github.com/rust-lang/rust-clippy/issues/3632

use serde_json;
use std::collections::HashMap;
use std::panic::RefUnwindSafe;

use super::Job;
use crate::util::CargoResult;

#[doc(hidden)]
pub type PerformFn<Env> =
    Box<dyn Fn(serde_json::Value, &Env) -> CargoResult<()> + RefUnwindSafe + Send + Sync>;

#[derive(Default)]
#[allow(missing_debug_implementations)] // Can't derive debug
/// A registry of background jobs, used to map job types to concrege perform
/// functions at runtime.
pub struct Registry<Env> {
    job_types: HashMap<&'static str, PerformFn<Env>>,
}

impl<Env> Registry<Env> {
    /// Create a new, empty registry
    pub fn new() -> Self {
        Registry {
            job_types: Default::default(),
        }
    }

    /// Get the perform function for a given job type
    pub fn get(&self, job_type: &str) -> Option<&PerformFn<Env>> {
        self.job_types.get(job_type)
    }

    /// Register a new background job. This will override any existing
    /// registries with the same `JOB_TYPE`, if one exists.
    pub fn register<T: Job<Environment = Env>>(&mut self) {
        self.job_types.insert(
            T::JOB_TYPE,
            Box::new(|data, env| {
                let data = serde_json::from_value(data)?;
                T::perform(data, env)
            }),
        );
    }
}
<|endoftext|>


<commit_before>use std::{io, fs, env};
use std::io::prelude::*;
use std::path::Path;

#[derive(Debug)]
struct Data {
    id: u64,
    api_duration: f64,
    latency: f64,
    gpu_duration: f64,
}

fn parse_csv(line: &str) -> Data {
    let mut inside = false;
    let mut col = line.trim().split('"').filter(|_| {
        inside = !inside;
        !inside
    });

    Data {
        id: col.next().unwrap().parse().unwrap(),
        api_duration: col.nth(2).unwrap().replace(',', "").parse().unwrap(),
        latency: col.next().unwrap().replace(',', "").parse().unwrap(),
        gpu_duration: col.nth(1).unwrap().replace(',', "").parse().unwrap(),
    }
}

fn parse_out(line: &str) -> Data {
    let mut split = line.split(',').map(|s| s.trim());
    Data {
        id: split.next().unwrap().parse().unwrap(),
        api_duration: split.next().unwrap().parse().unwrap(),
        latency: split.next().unwrap().parse().unwrap(),
        gpu_duration: split.next().unwrap().parse().unwrap(),
    }
}

fn transform_csv(input: &Path, output: &Path) {
    let mut r = io::BufReader::new(fs::File::open(input).unwrap());
    let mut w = io::BufWriter::new(fs::File::create(output).unwrap());

    let mut line = String::new();

    for _ in 0..11 {
        r.read_line(&mut line).unwrap();
        line.clear();
    }

    writeln!(w, "Transfer ID, API Duration(µs), Latency(µs), GPU Duration(µs)").unwrap();

    // Hypothesis: Sorted By GPU Start Time
    let mut prev: Option<Data> = None;
    while r.read_line(&mut line).unwrap() > 0 {
        let cur = parse_csv(&line);
        if let Some(mut p) = prev.take() {
            if p.id == cur.id {
                if p.latency < cur.latency { p.latency = cur.latency; }
                p.gpu_duration += cur.gpu_duration;
                prev = Some(p);
            } else {
                writeln!(w, "{}, {}, {}, {}", p.id, p.api_duration, p.latency, p.gpu_duration).unwrap();
                prev = Some(cur);
            }
        } else {
            prev = Some(cur);
        }

        line.clear();
    }

    if let Some(p) = prev.take() {
        writeln!(w, "{}, {}, {}, {}", p.id, p.api_duration, p.latency, p.gpu_duration).unwrap();
    }
}

struct Value {
    min: f64,
    max: f64,
    sum: f64,
}

impl Value {
    fn new() -> Value {
        Value {
            min: 1. / 0.,
            max: -1. / 0.,
            sum: 0.,
        }
    }

    fn add(&mut self, value: f64) {
        if value < self.min {
            self.min = value;
        }
        if value > self.max {
            self.max = value;
        }
        self.sum += value;
    }
}

fn process_results<W: io::Write>(directory: &Path, w: &mut W) {
    let mut api_duration = Value::new();
    let mut gpu_duration = Value::new();
    let mut n = 0f64;
    visit_dir(directory,
        &mut |path, _| if path.extension().map(|e| e == "out").unwrap_or(false) {
            let mut r = io::BufReader::new(fs::File::open(path).unwrap());
            let mut local_api_sum = 0f64;
            let mut local_gpu_sum = 0f64;
            let mut local_n = 0f64;
            let mut line = String::new();

            r.read_line(&mut line).unwrap();
            line.clear();
            while r.read_line(&mut line).unwrap() > 0 {
                let data = parse_out(&line);
                local_api_sum += data.api_duration;
                local_gpu_sum += data.gpu_duration;
                local_n += 1.;
                line.clear();
            }

            api_duration.add(local_api_sum / local_n);
            gpu_duration.add(local_gpu_sum / local_n);
            n += 1.;
        },
        &mut |_| {}
    ).unwrap();

    writeln!(w, "\"{}\", {}, {}, {}, {}, {}, {}", directory.display(),
        api_duration.min, api_duration.max, api_duration.sum / n,
        gpu_duration.min, gpu_duration.max, gpu_duration.sum / n).unwrap();
}

fn visit_dir<F, L>(dir: &Path, file_cb: &mut F, leaf_cb: &mut L) -> io::Result<()>
    where F: FnMut(&Path, fs::DirEntry), L: FnMut(&Path)
{
    if dir.is_dir() {
        let mut leaf = true;
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            let path = entry.path();
            if path.is_dir() {
                leaf = false;
                try!(visit_dir(&path, file_cb, leaf_cb));
            } else {
                file_cb(&path, entry);
            }
        }
        if leaf {
            leaf_cb(&dir);
        }
    }
    Ok(())
}

fn main() {
    let mut args = env::args().skip(1);
    let directory = args.next().unwrap_or_else(|| String::from("samples"));

    let results = Path::new(&directory).join("results");
    let mut w = io::BufWriter::new(fs::File::create(results).unwrap());

    visit_dir(directory.as_ref(),
        &mut |path, _| if path.extension().map(|e| e == "csv").unwrap_or(false) {
            let output = path.with_extension("out");
            if !output.exists() {
                println!("{} -> {}", path.display(), output.display());
                transform_csv(path, &output);
            }
        },
        &mut |leaf_path| {
            println!("processing {}", leaf_path.display());
            process_results(leaf_path, &mut w)
        }
    ).unwrap();

    println!("done!");
}<commit_msg>Better sample processing<commit_after>use std::{io, fs, env};
use std::io::prelude::*;
use std::path::Path;

#[derive(Debug)]
struct Data {
    id: u64,
    api_duration: f64,
    latency: f64,
    gpu_duration: f64,
}

fn parse_csv(line: &str) -> Data {
    let mut inside = false;
    let mut col = line.trim().split('"').filter(|_| {
        inside = !inside;
        !inside
    });

    Data {
        id: col.next().unwrap().parse().unwrap(),
        api_duration: col.nth(2).unwrap().replace(',', "").parse().unwrap(),
        latency: col.next().unwrap().replace(',', "").parse().unwrap(),
        gpu_duration: col.nth(1).unwrap().replace(',', "").parse().unwrap(),
    }
}

fn parse_out(line: &str) -> Data {
    let mut split = line.split(',').map(|s| s.trim());
    Data {
        id: split.next().unwrap().parse().unwrap(),
        api_duration: split.next().unwrap().parse().unwrap(),
        latency: split.next().unwrap().parse().unwrap(),
        gpu_duration: split.next().unwrap().parse().unwrap(),
    }
}

fn transform_csv(input: &Path, output: &Path) {
    let mut r = io::BufReader::new(fs::File::open(input).unwrap());
    let mut w = io::BufWriter::new(fs::File::create(output).unwrap());

    let mut line = String::new();

    for _ in 0..11 {
        r.read_line(&mut line).unwrap();
        line.clear();
    }

    writeln!(w, "Transfer ID, API Duration(µs), Latency(µs), GPU Duration(µs)").unwrap();

    // Hypothesis: Sorted By GPU Start Time
    let mut prev: Option<Data> = None;
    while r.read_line(&mut line).unwrap() > 0 {
        let cur = parse_csv(&line);
        if let Some(mut p) = prev.take() {
            if p.id == cur.id {
                if p.latency < cur.latency { p.latency = cur.latency; }
                p.gpu_duration += cur.gpu_duration;
                prev = Some(p);
            } else {
                writeln!(w, "{}, {}, {}, {}", p.id, p.api_duration, p.latency, p.gpu_duration).unwrap();
                prev = Some(cur);
            }
        } else {
            prev = Some(cur);
        }

        line.clear();
    }

    if let Some(p) = prev.take() {
        writeln!(w, "{}, {}, {}, {}", p.id, p.api_duration, p.latency, p.gpu_duration).unwrap();
    }
}

struct Value {
    min: f64,
    max: f64,
    sum: f64,
    sq_sum: f64,
}

impl Value {
    fn new() -> Value {
        Value {
            min: 1. / 0.,
            max: -1. / 0.,
            sum: 0.,
            sq_sum: 0.
        }
    }

    fn add(&mut self, value: f64) {
        if value < self.min {
            self.min = value;
        }
        if value > self.max {
            self.max = value;
        }
        self.sum += value;
        self.sq_sum += value.powi(2);
    }

    fn write<W: io::Write>(&self, n: f64, w: &mut W) {
        let avg = self.sum / n;
        let var = self.sq_sum / n - avg.powi(2);
        write!(w, ",{},{},{},{},{}", self.min, self.max, avg, var, var.sqrt()).unwrap();
    }

    fn write_header<W: io::Write>(prefix: &str, w: &mut W) {
        write!(w, ",\"{0}{1}\",\"{0}{2}\",\"{0}{3}\",\"{0}{4}\",\"{0}{5}\"",
            prefix, "min", "max", "avg", "var", "stddev").unwrap();
    }
}

fn process_results<W: io::Write>(directory: &Path, w: &mut W) {
    let mut api_duration = Value::new();
    let mut gpu_duration = Value::new();
    let mut n = 0f64;
    visit_dir(directory,
        &mut |path, _| if path.extension().map(|e| e == "out").unwrap_or(false) {
            let mut r = io::BufReader::new(fs::File::open(path).unwrap());
            let mut api_sum = 0f64;
            let mut gpu_sum = 0f64;
            let mut line = String::new();

            r.read_line(&mut line).unwrap();
            line.clear();
            while r.read_line(&mut line).unwrap() > 0 {
                let data = parse_out(&line);
                api_sum += data.api_duration;
                gpu_sum += data.gpu_duration;
                line.clear();
            }

            api_duration.add(api_sum);
            gpu_duration.add(gpu_sum);
            n += 1.;
        },
        &mut |_| {}
    ).unwrap();

    write!(w, "\"{}\"", directory.display()).unwrap();
    api_duration.write(n, w);
    gpu_duration.write(n, w);
    writeln!(w, "").unwrap();
}

fn visit_dir<F, L>(dir: &Path, file_cb: &mut F, leaf_cb: &mut L) -> io::Result<()>
    where F: FnMut(&Path, fs::DirEntry), L: FnMut(&Path)
{
    if dir.is_dir() {
        let mut leaf = true;
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            let path = entry.path();
            if path.is_dir() {
                leaf = false;
                try!(visit_dir(&path, file_cb, leaf_cb));
            } else {
                file_cb(&path, entry);
            }
        }
        if leaf {
            leaf_cb(&dir);
        }
    }
    Ok(())
}

fn main() {
    let mut args = env::args().skip(1);
    let directory = args.next().unwrap_or_else(|| String::from("samples"));

    let results = Path::new(&directory).join("results");
    let mut w = io::BufWriter::new(fs::File::create(results).unwrap());
    write!(w, "\"Directory\"").unwrap();
    Value::write_header("API duration ", &mut w);
    Value::write_header("GPU duration ", &mut w);
    writeln!(w, "").unwrap();

    visit_dir(directory.as_ref(),
        &mut |path, _| if path.extension().map(|e| e == "csv").unwrap_or(false) {
            let output = path.with_extension("out");
            if !output.exists() {
                println!("{} -> {}", path.display(), output.display());
                transform_csv(path, &output);
            }
        },
        &mut |leaf_path| {
            println!("processing {}", leaf_path.display());
            process_results(leaf_path, &mut w)
        }
    ).unwrap();

    println!("done!");
}<|endoftext|>


<commit_before>#![feature(phase)]
extern crate serialize;

#[phase(plugin)]
extern crate docopt_macros;
extern crate docopt;

extern crate rustscripts;

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unnecessary_qualification)]
#[warn(non_uppercase_statics)]
#[warn(missing_doc)]

/** Creates fake words.
 *  First, it uses a predefined list of words to generate a markov chain
 *  for word prefixes; it then probabilistically follows this to generate
 *  fake words.
**/

use docopt::FlagParser;

use std::collections::{HashSet,HashMap};
use std::rand;
use std::rand::Rng;
use std::io::{File,BufferedReader};

use rustscripts::counter;

//* Build a HashMap of "substring" : "number of occurrences"
fn to_hashes(wordlist : &[String], sublens : uint) -> HashMap<String, uint> {
	println!("Got wordlist, length {}", wordlist.len());

	let iter = wordlist.iter().filter(|k| {
		let kslice = k.as_slice();
		if kslice.char_len() == 0 {false}
		else if kslice.contains("\'") {false}
		else if kslice.find(|c : char|{!c.is_lowercase()}).is_some() {false}
		else {true}
	});
	let trimchars : &[char] = &[' ', '\t', '\r', '\n'];
	let iter = iter.flat_map(|k| {
		let kslice = k.as_slice();
		let fullword = (["^", kslice.trim_chars(trimchars), "$"]).concat();
        let fullchars : Vec<char> = fullword.as_slice().chars().collect();

        let chvec : Vec<String> =
		fullchars.as_slice().windows(sublens).map(|chars| {
			String::from_chars(chars)
		})
		.collect();

		//~ println!("k: {}, chvec: {}", k, chvec);

		chvec.into_iter()
	});
	counter(iter)
}

struct WordBuilder {
    subs : HashMap<String, uint>,
    // list : Vec<String>,
    // sublens : uint,
    wordset : HashSet<String>,
    wordlens : Vec<uint>
}

struct WordIter<'a> {
    p : &'a mut WordBuilder
}

impl WordBuilder {
    fn new(list : Vec<String>, sublens : uint) -> WordBuilder {
        let mut h = HashSet::new();
        let mut wlens : Vec<uint> = Vec::new();
        for w in list.iter() {
            h.insert(w.to_string());
            let wordlen = w.len();
            for _ in range(wlens.len(), wordlen+1){
                wlens.push(0);
            }
            let n = wlens.get_mut(wordlen);
            *n += 1;
        }

        WordBuilder {
            subs : to_hashes(list.as_slice(), sublens),
            //list : list,
            //sublens : sublens,
            wordset : h,
            wordlens : wlens
        }
    }

    fn word(&mut self) -> Option<String> {
        let mut s : String = "^".to_string();

        loop {
            let mut fullsum = 0u;
            let mut endsum = 0u;
            let possibilities : Vec<(&str, uint)> = self.subs.iter().filter_map(
                |(k,v)| {
                    /* the beginning of k and the end of s must match for
                     * k to be a possibility
                     * if s is long, then the first (klength - 1) letters
                     * of k must match the last (klength - 1) letters of s
                     * otherwise, the first (slength) characters
                    */
                    let slen = s.as_slice().char_len();
                    let kslice = k.as_slice();
                    let klen = kslice.char_len();
                    let kcut = if slen < klen - 1 {slen} else {klen - 1};
                    if s.as_slice().ends_with(kslice.slice_chars(0, kcut)){
                        fullsum += *v;
                        if kslice.ends_with("$") {endsum += *v;}
                        Some((kslice,*v))
                    } else {None}
                }
            ).collect();
            if fullsum == 0 {
                fail!("s: \"{}\"", s);
            }

            let endprob = if self.wordlens.len() > s.len() {
                let wordlenslice : &[uint] = self.wordlens.slice(s.len()-1, self.wordlens.len());
                let c = wordlenslice[0];
                let l = wordlenslice.iter().fold(0, |a,&b|{a+b});
                (c as f64) / (l as f64)
            } else {
                //~ println!("Too long: {}", s);
                return None;
            };

            let randnum = rand::task_rng().gen_range(0.0, 1.0);

            let endtime = randnum < endprob;
            if (endtime && (endsum == 0)) || ((!endtime) && (fullsum-endsum==0)) {
                //~ println!("Failed to end: {}", s);
                return None;
            }

            //~ println!("endtime: {} {} : ({},{}) {}", endtime, randnum < endprob,
                //~ endsum, fullsum, if(endtime){endsum} else {fullsum - endsum});
            let randnum = rand::task_rng().gen_range(0.0,
                (if endtime {endsum} else {fullsum - endsum} as f64));

            let mut psum = 0;

            for &(k,v) in possibilities.iter() {
                if endtime ^ k.ends_with("$") {continue;};

                if randnum < ((psum + v) as f64) {
                    let slen = s.as_slice().char_len();
                    let klen = k.char_len();
                    let kcut = if slen < klen - 1 {slen} else {klen - 1};
                    //~ let olds = s.to_string();
                    s.push_str(k.slice_chars(kcut,klen));
                    break;
                }
                psum += v;
            }

            let slen = s.as_slice().char_len();
            if s.as_slice().slice_chars(slen-1, slen) == "$" {
                return Some(s.as_slice().slice_chars(1, slen-1).to_string());
            }
        };
    }

    fn iter<'a>(&'a mut self) -> WordIter<'a> {
        WordIter{p:self}
    }
}

impl<'a> Iterator<String> for WordIter<'a> {
    fn next(&mut self) -> Option<String> {
        loop {
            let optw = self.p.word();
            match optw {
                None => {},
                Some(w) => {
                    if !self.p.wordset.contains(&w)
                        {return Some(w)};
                }
            };
        }
    }
}

docopt!(Args, "
Usage: fakewords2 [-h | --help] [-n <number>] [<dictfile>]

Options:
    -n <number>    use number length substrings for markovian chain
    <dictfile>     use dictfile instead of /usr/share/dict/words
", flag_n : Option<uint>, arg_dictfile : Option<String>)

pub fn main(){
	let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

    let flag_n : Option<uint> = args.flag_n;

    let subsetn : uint = flag_n.unwrap_or(4u);

    let pathstr = args.arg_dictfile.map(|s| {s}).unwrap_or("/usr/share/dict/words".to_string());

    let path = Path::new(pathstr);
    //~ let path = Path::new("fakewords-test.txt");
    let mut file = BufferedReader::new(File::open(&path));

    let trimchars : &[char] = &[' ', '\t', '\r', '\n'];

    let lines: Vec<String> = file.lines().map(|orl| {
		orl.unwrap().as_slice().trim_chars(trimchars).to_string()
	}).collect();
    let mut wb = WordBuilder::new(lines, subsetn);

    println!("Now have a map of length {}", wb.subs.len());

    for w in wb.iter(){
        println!("{}",w);
    }
}
<commit_msg>Better error handling for fakewords<commit_after>#![feature(phase)]
extern crate serialize;

#[phase(plugin)]
extern crate docopt_macros;
extern crate docopt;

extern crate rustscripts;

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unnecessary_qualification)]
#[warn(non_uppercase_statics)]
#[warn(missing_doc)]

/** Creates fake words.
 *  First, it uses a predefined list of words to generate a markov chain
 *  for word prefixes; it then probabilistically follows this to generate
 *  fake words.
**/

use docopt::FlagParser;

use std::collections::{HashSet,HashMap};
use std::rand;
use std::rand::Rng;
use std::io::{File,BufferedReader};

use rustscripts::counter;

//* Build a HashMap of "substring" : "number of occurrences"
fn to_hashes(wordlist : &[String], sublens : uint) -> HashMap<String, uint> {
	println!("Got wordlist, length {}", wordlist.len());

	let iter = wordlist.iter().filter(|k| {
		let kslice = k.as_slice();
		if kslice.char_len() == 0 {false}
		else if kslice.contains("\'") {false}
		else if kslice.find(|c : char|{!c.is_lowercase()}).is_some() {false}
		else {true}
	});
	let trimchars : &[char] = &[' ', '\t', '\r', '\n'];
	let iter = iter.flat_map(|k| {
		let kslice = k.as_slice();
		let fullword = (["^", kslice.trim_chars(trimchars), "$"]).concat();
        let fullchars : Vec<char> = fullword.as_slice().chars().collect();

        let chvec : Vec<String> =
		fullchars.as_slice().windows(sublens).map(|chars| {
			String::from_chars(chars)
		})
		.collect();

		//~ println!("k: {}, chvec: {}", k, chvec);

		chvec.into_iter()
	});
	counter(iter)
}

struct WordBuilder {
    subs : HashMap<String, uint>,
    // list : Vec<String>,
    // sublens : uint,
    wordset : HashSet<String>,
    wordlens : Vec<uint>
}

struct WordIter<'a> {
    p : &'a mut WordBuilder
}

impl WordBuilder {
    fn new(list : Vec<String>, sublens : uint) -> WordBuilder {
        let mut h = HashSet::new();
        let mut wlens : Vec<uint> = Vec::new();
        for w in list.iter() {
            h.insert(w.to_string());
            let wordlen = w.len();
            for _ in range(wlens.len(), wordlen+1){
                wlens.push(0);
            }
            let n = wlens.get_mut(wordlen);
            *n += 1;
        }

        WordBuilder {
            subs : to_hashes(list.as_slice(), sublens),
            //list : list,
            //sublens : sublens,
            wordset : h,
            wordlens : wlens
        }
    }

    fn word(&mut self) -> Option<String> {
        let mut s : String = "^".to_string();

        loop {
            let mut fullsum = 0u;
            let mut endsum = 0u;
            let possibilities : Vec<(&str, uint)> = self.subs.iter().filter_map(
                |(k,v)| {
                    /* the beginning of k and the end of s must match for
                     * k to be a possibility
                     * if s is long, then the first (klength - 1) letters
                     * of k must match the last (klength - 1) letters of s
                     * otherwise, the first (slength) characters
                    */
                    let slen = s.as_slice().char_len();
                    let kslice = k.as_slice();
                    let klen = kslice.char_len();
                    let kcut = if slen < klen - 1 {slen} else {klen - 1};
                    if s.as_slice().ends_with(kslice.slice_chars(0, kcut)){
                        fullsum += *v;
                        if kslice.ends_with("$") {endsum += *v;}
                        Some((kslice,*v))
                    } else {None}
                }
            ).collect();
            if fullsum == 0 {
                fail!("s: \"{}\"", s);
            }

            let endprob = if self.wordlens.len() > s.len() {
                let wordlenslice : &[uint] = self.wordlens.slice(s.len()-1, self.wordlens.len());
                let c = wordlenslice[0];
                let l = wordlenslice.iter().fold(0, |a,&b|{a+b});
                (c as f64) / (l as f64)
            } else {
                //~ println!("Too long: {}", s);
                return None;
            };

            let randnum = rand::task_rng().gen_range(0.0, 1.0);

            let endtime = randnum < endprob;
            if (endtime && (endsum == 0)) || ((!endtime) && (fullsum-endsum==0)) {
                //~ println!("Failed to end: {}", s);
                return None;
            }

            //~ println!("endtime: {} {} : ({},{}) {}", endtime, randnum < endprob,
                //~ endsum, fullsum, if(endtime){endsum} else {fullsum - endsum});
            let randnum = rand::task_rng().gen_range(0.0,
                (if endtime {endsum} else {fullsum - endsum} as f64));

            let mut psum = 0;

            for &(k,v) in possibilities.iter() {
                if endtime ^ k.ends_with("$") {continue;};

                if randnum < ((psum + v) as f64) {
                    let slen = s.as_slice().char_len();
                    let klen = k.char_len();
                    let kcut = if slen < klen - 1 {slen} else {klen - 1};
                    //~ let olds = s.to_string();
                    s.push_str(k.slice_chars(kcut,klen));
                    break;
                }
                psum += v;
            }

            let slen = s.as_slice().char_len();
            if s.as_slice().slice_chars(slen-1, slen) == "$" {
                return Some(s.as_slice().slice_chars(1, slen-1).to_string());
            }
        };
    }

    fn iter<'a>(&'a mut self) -> WordIter<'a> {
        WordIter{p:self}
    }
}

impl<'a> Iterator<String> for WordIter<'a> {
    fn next(&mut self) -> Option<String> {
        loop {
            let optw = self.p.word();
            match optw {
                None => {},
                Some(w) => {
                    if !self.p.wordset.contains(&w)
                        {return Some(w)};
                }
            };
        }
    }
}

docopt!(Args, "
Usage: fakewords2 [-h | --help] [-n <number>] [<dictfile>]

Options:
    -n <number>    use number length substrings for markovian chain
    <dictfile>     use dictfile instead of /usr/share/dict/words
", flag_n : Option<uint>, arg_dictfile : Option<String>)

pub fn main(){
	let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

    let flag_n : Option<uint> = args.flag_n;

    let subsetn : uint = flag_n.unwrap_or(4u);

    let pathstr = args.arg_dictfile.map(|s| {s}).unwrap_or("/usr/share/dict/words".to_string());

    let path = Path::new(pathstr.clone());
    let file = match File::open(&path) {
		Ok(f) => f,
		Err(std::io::IoError{kind: std::io::FileNotFound, desc: _, detail: _}) => {
			let _ = writeln!(std::io::stderr(), "File not found: {}", pathstr);
			std::os::set_exit_status(-1);
			return;
		}
		Err(e) => fail!("failed to open file: {}", e)
	};

    let mut file = BufferedReader::new(file);

    let trimchars : &[char] = &[' ', '\t', '\r', '\n'];

    let lines: Vec<String> = file.lines().map(|orl| {
		let unwrapl = match orl {
			Ok(l) => l,
			Err(e) => fail!("Failed reading file: {}", e)
		};
		unwrapl.as_slice().trim_chars(trimchars).to_string()
	}).collect();
    let mut wb = WordBuilder::new(lines, subsetn);

    println!("Now have a map of length {}", wb.subs.len());

    for w in wb.iter(){
        println!("{}",w);
    };
}
<|endoftext|>


<commit_before>use std::default::Default;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::PathBuf;
use std::str::FromStr;

use toml;

pub use bindgen::directive::*;
pub use bindgen::rename::*;

pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, Clone, PartialEq)]
pub enum Language {
    Cxx,
    C,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Braces {
    SameLine,
    NextLine,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Layout {
    Horizontal,
    Vertical,
    Auto,
}

impl FromStr for Language {
    type Err = String;

    fn from_str(s: &str) -> Result<Language, Self::Err> {
        match s {
            "cxx" => Ok(Language::Cxx),
            "Cxx" => Ok(Language::Cxx),
            "CXX" => Ok(Language::Cxx),
            "cpp" => Ok(Language::Cxx),
            "Cpp" => Ok(Language::Cxx),
            "CPP" => Ok(Language::Cxx),
            "c++" => Ok(Language::Cxx),
            "C++" => Ok(Language::Cxx),
            "c" => Ok(Language::C),
            "C" => Ok(Language::C),
            _ => Err(format!("unrecognized Language: '{}'", s)),
        }
    }
}
impl FromStr for Braces {
    type Err = String;

    fn from_str(s: &str) -> Result<Braces, Self::Err> {
        match s {
            "SameLine" => Ok(Braces::SameLine),
            "same_line" => Ok(Braces::SameLine),
            "NextLine" => Ok(Braces::NextLine),
            "next_line" => Ok(Braces::NextLine),
            _ => Err(format!("unrecognized Braces: '{}'", s)),
        }
    }
}
impl FromStr for Layout {
    type Err = String;

    fn from_str(s: &str) -> Result<Layout, Self::Err> {
        match s {
            "Horizontal" => Ok(Layout::Horizontal),
            "horizontal" => Ok(Layout::Horizontal),
            "Vertical" => Ok(Layout::Vertical),
            "vertical" => Ok(Layout::Vertical),
            "Auto" => Ok(Layout::Auto),
            "auto" => Ok(Layout::Auto),
            _ => Err(format!("unrecognized Layout: '{}'", s)),
        }
    }
}

deserialize_enum_str!(Language);
deserialize_enum_str!(Braces);
deserialize_enum_str!(Layout);

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Config {
    /// Optional text to output at the beginning of the file
    pub header: Option<String>,
    /// Optional text to output at the end of the file
    pub trailer: Option<String>,
    /// Option name to use for an include guard
    pub include_guard: Option<String>,
    /// Optional text to output at major sections to deter manual editing
    pub autogen_warning: Option<String>,
    /// Include a comment with the version of cbindgen used to generate the file
    pub include_version: bool,
    /// The style to use for braces
    pub braces: Braces,
    /// The preferred length of a line, used for auto breaking function arguments
    pub line_length: usize,
    /// The amount of spaces in a tab
    pub tab_width: usize,
    /// The language to output bindings for
    pub language: Language,
    /// The configuration options for functions
    #[serde(rename = "fn")]
    pub function: FunctionConfig,
    /// The configuration options for structs
    #[serde(rename = "struct")]
    pub structure: StructConfig,
    /// The configuration options for enums
    #[serde(rename = "enum")]
    pub enumeration: EnumConfig,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            header: None,
            trailer: None,
            include_guard: None,
            autogen_warning: None,
            include_version: true,
            braces: Braces::SameLine,
            line_length: 100,
            tab_width: 2,
            language: Language::C,
            function: FunctionConfig::default(),
            structure: StructConfig::default(),
            enumeration: EnumConfig::default(),
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct FunctionConfig {
    /// Optional text to output before each function declaration
    pub prefix: Option<String>,
    /// Optional text to output after each function declaration
    pub postfix: Option<String>,
    /// The style to layout the args
    pub args: Layout,
    /// The rename rule to apply to function args
    pub rename_args: Option<RenameRule>,
}

impl Default for FunctionConfig {
    fn default() -> FunctionConfig {
        FunctionConfig {
            prefix: None,
            postfix: None,
            args: Layout::Auto,
            rename_args: None,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct StructConfig {
    /// The rename rule to apply to the name of struct fields
    pub rename_fields: Option<RenameRule>,
    /// Whether to generate a piecewise equality operator
    pub derive_eq: bool,
    /// Whether to generate a piecewise inequality operator
    pub derive_neq: bool,
    /// Whether to generate a less than operator on structs with one field
    pub derive_lt: bool,
    /// Whether to generate a less than or equal to operator on structs with one field
    pub derive_lte: bool,
    /// Whether to generate a greater than operator on structs with one field
    pub derive_gt: bool,
    /// Whether to generate a greater than or equal to operator on structs with one field
    pub derive_gte: bool,
}

impl Default for StructConfig {
    fn default() -> StructConfig {
        StructConfig {
            rename_fields: None,
            derive_eq: false,
            derive_neq: false,
            derive_lt: false,
            derive_lte: false,
            derive_gt: false,
            derive_gte: false,
        }
    }
}

#[derive( Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct EnumConfig {
    /// The rename rule to apply to the name of enum variants
    pub rename_variants: Option<RenameRule>,
    /// Whether to add a `Sentinel` value at the end of every enum
    /// This is useful in Gecko for IPC serialization
    pub add_sentinel: bool,
}

impl Default for EnumConfig {
    fn default() -> EnumConfig {
        EnumConfig {
            rename_variants: None,
            add_sentinel: false,
        }
    }
}

impl Config {
    pub fn from_file(file_name: &str) -> Result<Config, String> {
        fn read(file_name: &str) -> io::Result<String> {
            let file = File::open(file_name)?;
            let mut reader = BufReader::new(&file);
            let mut contents = String::new();
            reader.read_to_string(&mut contents)?;
            Ok(contents)
        }

        let config_text = read(file_name).unwrap();

        match toml::from_str::<Config>(&config_text) {
            Ok(x) => Ok(x),
            Err(e) => Err(format!("couldn't parse config file: {}", e)),
        }
    }

    pub fn from_root_or_default(root: &str) -> Config {
        let c = PathBuf::from(root).join("cbindgen.toml");

        if c.exists() {
            Config::from_file(c.to_str().unwrap()).unwrap()
        } else {
            Config::default()
        }
    }
}

impl FunctionConfig {
    pub fn prefix(&self, directives: &DirectiveSet) -> Option<String> {
        if let Some(x) = directives.atom("prefix") {
            return x;
        }
        self.prefix.clone()
    }

    pub fn postfix(&self, directives: &DirectiveSet) -> Option<String> {
        if let Some(x) = directives.atom("postfix") {
            return x;
        }
        self.postfix.clone()
    }
}

impl StructConfig {
    pub fn derive_eq(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-eq") {
            return x;
        }
        self.derive_eq
    }
    pub fn derive_neq(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-neq") {
            return x;
        }
        self.derive_neq
    }
    pub fn derive_lt(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-lt") {
            return x;
        }
        self.derive_lt
    }
    pub fn derive_lte(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-lte") {
            return x;
        }
        self.derive_lte
    }
    pub fn derive_gt(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-gt") {
            return x;
        }
        self.derive_gt
    }
    pub fn derive_gte(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-gte") {
            return x;
        }
        self.derive_gte
    }
}

impl EnumConfig {
    pub fn add_sentinel(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("add-sentinel") {
            return x;
        }
        self.add_sentinel
    }
}
<commit_msg>Default to generating C++<commit_after>use std::default::Default;
use std::fs::File;
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::PathBuf;
use std::str::FromStr;

use toml;

pub use bindgen::directive::*;
pub use bindgen::rename::*;

pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, Clone, PartialEq)]
pub enum Language {
    Cxx,
    C,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Braces {
    SameLine,
    NextLine,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Layout {
    Horizontal,
    Vertical,
    Auto,
}

impl FromStr for Language {
    type Err = String;

    fn from_str(s: &str) -> Result<Language, Self::Err> {
        match s {
            "cxx" => Ok(Language::Cxx),
            "Cxx" => Ok(Language::Cxx),
            "CXX" => Ok(Language::Cxx),
            "cpp" => Ok(Language::Cxx),
            "Cpp" => Ok(Language::Cxx),
            "CPP" => Ok(Language::Cxx),
            "c++" => Ok(Language::Cxx),
            "C++" => Ok(Language::Cxx),
            "c" => Ok(Language::C),
            "C" => Ok(Language::C),
            _ => Err(format!("unrecognized Language: '{}'", s)),
        }
    }
}
impl FromStr for Braces {
    type Err = String;

    fn from_str(s: &str) -> Result<Braces, Self::Err> {
        match s {
            "SameLine" => Ok(Braces::SameLine),
            "same_line" => Ok(Braces::SameLine),
            "NextLine" => Ok(Braces::NextLine),
            "next_line" => Ok(Braces::NextLine),
            _ => Err(format!("unrecognized Braces: '{}'", s)),
        }
    }
}
impl FromStr for Layout {
    type Err = String;

    fn from_str(s: &str) -> Result<Layout, Self::Err> {
        match s {
            "Horizontal" => Ok(Layout::Horizontal),
            "horizontal" => Ok(Layout::Horizontal),
            "Vertical" => Ok(Layout::Vertical),
            "vertical" => Ok(Layout::Vertical),
            "Auto" => Ok(Layout::Auto),
            "auto" => Ok(Layout::Auto),
            _ => Err(format!("unrecognized Layout: '{}'", s)),
        }
    }
}

deserialize_enum_str!(Language);
deserialize_enum_str!(Braces);
deserialize_enum_str!(Layout);

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct Config {
    /// Optional text to output at the beginning of the file
    pub header: Option<String>,
    /// Optional text to output at the end of the file
    pub trailer: Option<String>,
    /// Option name to use for an include guard
    pub include_guard: Option<String>,
    /// Optional text to output at major sections to deter manual editing
    pub autogen_warning: Option<String>,
    /// Include a comment with the version of cbindgen used to generate the file
    pub include_version: bool,
    /// The style to use for braces
    pub braces: Braces,
    /// The preferred length of a line, used for auto breaking function arguments
    pub line_length: usize,
    /// The amount of spaces in a tab
    pub tab_width: usize,
    /// The language to output bindings for
    pub language: Language,
    /// The configuration options for functions
    #[serde(rename = "fn")]
    pub function: FunctionConfig,
    /// The configuration options for structs
    #[serde(rename = "struct")]
    pub structure: StructConfig,
    /// The configuration options for enums
    #[serde(rename = "enum")]
    pub enumeration: EnumConfig,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            header: None,
            trailer: None,
            include_guard: None,
            autogen_warning: None,
            include_version: true,
            braces: Braces::SameLine,
            line_length: 100,
            tab_width: 2,
            language: Language::Cxx,
            function: FunctionConfig::default(),
            structure: StructConfig::default(),
            enumeration: EnumConfig::default(),
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct FunctionConfig {
    /// Optional text to output before each function declaration
    pub prefix: Option<String>,
    /// Optional text to output after each function declaration
    pub postfix: Option<String>,
    /// The style to layout the args
    pub args: Layout,
    /// The rename rule to apply to function args
    pub rename_args: Option<RenameRule>,
}

impl Default for FunctionConfig {
    fn default() -> FunctionConfig {
        FunctionConfig {
            prefix: None,
            postfix: None,
            args: Layout::Auto,
            rename_args: None,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct StructConfig {
    /// The rename rule to apply to the name of struct fields
    pub rename_fields: Option<RenameRule>,
    /// Whether to generate a piecewise equality operator
    pub derive_eq: bool,
    /// Whether to generate a piecewise inequality operator
    pub derive_neq: bool,
    /// Whether to generate a less than operator on structs with one field
    pub derive_lt: bool,
    /// Whether to generate a less than or equal to operator on structs with one field
    pub derive_lte: bool,
    /// Whether to generate a greater than operator on structs with one field
    pub derive_gt: bool,
    /// Whether to generate a greater than or equal to operator on structs with one field
    pub derive_gte: bool,
}

impl Default for StructConfig {
    fn default() -> StructConfig {
        StructConfig {
            rename_fields: None,
            derive_eq: false,
            derive_neq: false,
            derive_lt: false,
            derive_lte: false,
            derive_gt: false,
            derive_gte: false,
        }
    }
}

#[derive( Debug, Clone, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct EnumConfig {
    /// The rename rule to apply to the name of enum variants
    pub rename_variants: Option<RenameRule>,
    /// Whether to add a `Sentinel` value at the end of every enum
    /// This is useful in Gecko for IPC serialization
    pub add_sentinel: bool,
}

impl Default for EnumConfig {
    fn default() -> EnumConfig {
        EnumConfig {
            rename_variants: None,
            add_sentinel: false,
        }
    }
}

impl Config {
    pub fn from_file(file_name: &str) -> Result<Config, String> {
        fn read(file_name: &str) -> io::Result<String> {
            let file = File::open(file_name)?;
            let mut reader = BufReader::new(&file);
            let mut contents = String::new();
            reader.read_to_string(&mut contents)?;
            Ok(contents)
        }

        let config_text = read(file_name).unwrap();

        match toml::from_str::<Config>(&config_text) {
            Ok(x) => Ok(x),
            Err(e) => Err(format!("couldn't parse config file: {}", e)),
        }
    }

    pub fn from_root_or_default(root: &str) -> Config {
        let c = PathBuf::from(root).join("cbindgen.toml");

        if c.exists() {
            Config::from_file(c.to_str().unwrap()).unwrap()
        } else {
            Config::default()
        }
    }
}

impl FunctionConfig {
    pub fn prefix(&self, directives: &DirectiveSet) -> Option<String> {
        if let Some(x) = directives.atom("prefix") {
            return x;
        }
        self.prefix.clone()
    }

    pub fn postfix(&self, directives: &DirectiveSet) -> Option<String> {
        if let Some(x) = directives.atom("postfix") {
            return x;
        }
        self.postfix.clone()
    }
}

impl StructConfig {
    pub fn derive_eq(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-eq") {
            return x;
        }
        self.derive_eq
    }
    pub fn derive_neq(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-neq") {
            return x;
        }
        self.derive_neq
    }
    pub fn derive_lt(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-lt") {
            return x;
        }
        self.derive_lt
    }
    pub fn derive_lte(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-lte") {
            return x;
        }
        self.derive_lte
    }
    pub fn derive_gt(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-gt") {
            return x;
        }
        self.derive_gt
    }
    pub fn derive_gte(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("derive-gte") {
            return x;
        }
        self.derive_gte
    }
}

impl EnumConfig {
    pub fn add_sentinel(&self, directives: &DirectiveSet) -> bool {
        if let Some(x) = directives.bool("add-sentinel") {
            return x;
        }
        self.add_sentinel
    }
}
<|endoftext|>


<commit_before>pub trait BitFlags<T>:
    core::ops::BitOr<Output = Self>
    + core::ops::BitOrAssign
    + core::ops::BitXor<Output = Self>
    + core::ops::BitXorAssign
    + core::ops::BitAnd<Output = Self>
    + core::ops::BitAndAssign
    + core::ops::Sub<Output = Self>
    + core::ops::SubAssign
    + core::ops::Not<Output = Self>
    + core::iter::Extend<Self>
    + core::iter::FromIterator<Self>
    + core::fmt::Debug
    + core::cmp::PartialEq<Self>
    + core::cmp::Eq
    + core::cmp::PartialOrd<Self>
    + core::cmp::Ord
    + core::hash::Hash
    + Copy
    + core::fmt::Octal
    + core::fmt::Binary
    + core::fmt::LowerHex
    + core::fmt::UpperHex
    + Clone
{
    /// Returns an empty set of flags.
    fn empty() -> Self;
    /// Returns the set containing all flags.
    fn all() -> Self;
    /// Returns the raw value of the flags currently stored.
    fn bits(&self) -> T;
    /// Convert from underlying bit representation, unless that
    /// representation contains bits that do not correspond to a flag.
    fn from_bits(bits: T) -> core::option::Option<Self>;
    /// Convert from underlying bit representation, dropping any bits
    /// that do not correspond to flags.
    unsafe fn from_bits_truncate(bits: T) -> Self;
    /// Convert from underlying bit representation, preserving all
    /// bits (even those not corresponding to a defined flag).
    ///
    /// # Safety
    ///
    /// The caller of the `bitflags!` macro can chose to allow or
    /// disallow extra bits for their bitflags type.
    ///
    /// The caller of `from_bits_unchecked()` has to ensure that
    /// all bits correspond to a defined flag or that extra bits
    /// are valid for this bitflags type.
    unsafe fn from_bits_unchecked(bits: T) -> Self;
    /// Returns `true` if no flags are currently stored.
    fn is_empty(&self) -> bool;
    /// Returns `true` if all flags are currently set.
    fn is_all(&self) -> bool;
    /// Returns `true` if there are flags common to both `self` and `other`.
    fn intersects(&self, other: Self) -> bool;
    /// Returns `true` all of the flags in `other` are contained within `self`.
    fn contains(&self, other: Self) -> bool;
    /// Inserts the specified flags in-place.
    fn insert(&mut self, other: Self);
    /// Removes the specified flags in-place.
    fn remove(&mut self, other: Self);
    /// Toggles the specified flags in-place.
    fn toggle(&mut self, other: Self);
    /// Inserts or removes the specified flags depending on the passed value.
    fn set(&mut self, other: Self, value: bool);
}
<commit_msg>fix trait bounds for older compilers<commit_after>use core as _core;

pub trait BitFlags<T>:
    _core::ops::BitOr<Output = Self>
    + _core::ops::BitOrAssign
    + _core::ops::BitXor<Output = Self>
    + _core::ops::BitXorAssign
    + _core::ops::BitAnd<Output = Self>
    + _core::ops::BitAndAssign
    + _core::ops::Sub<Output = Self>
    + _core::ops::SubAssign
    + _core::ops::Not<Output = Self>
    + _core::iter::Extend<Self>
    + _core::iter::FromIterator<Self>
    + _core::fmt::Debug
    + _core::cmp::PartialEq<Self>
    + _core::cmp::Eq
    + _core::cmp::PartialOrd<Self>
    + _core::cmp::Ord
    + _core::hash::Hash
    + _core::fmt::Octal
    + _core::fmt::Binary
    + _core::fmt::LowerHex
    + _core::fmt::UpperHex
    + Clone
    + Copy
{
    /// Returns an empty set of flags.
    fn empty() -> Self;
    /// Returns the set containing all flags.
    fn all() -> Self;
    /// Returns the raw value of the flags currently stored.
    fn bits(&self) -> T;
    /// Convert from underlying bit representation, unless that
    /// representation contains bits that do not correspond to a flag.
    fn from_bits(bits: T) -> core::option::Option<Self>;
    /// Convert from underlying bit representation, dropping any bits
    /// that do not correspond to flags.
    unsafe fn from_bits_truncate(bits: T) -> Self;
    /// Convert from underlying bit representation, preserving all
    /// bits (even those not corresponding to a defined flag).
    ///
    /// # Safety
    ///
    /// The caller of the `bitflags!` macro can chose to allow or
    /// disallow extra bits for their bitflags type.
    ///
    /// The caller of `from_bits_unchecked()` has to ensure that
    /// all bits correspond to a defined flag or that extra bits
    /// are valid for this bitflags type.
    unsafe fn from_bits_unchecked(bits: T) -> Self;
    /// Returns `true` if no flags are currently stored.
    fn is_empty(&self) -> bool;
    /// Returns `true` if all flags are currently set.
    fn is_all(&self) -> bool;
    /// Returns `true` if there are flags common to both `self` and `other`.
    fn intersects(&self, other: Self) -> bool;
    /// Returns `true` all of the flags in `other` are contained within `self`.
    fn contains(&self, other: Self) -> bool;
    /// Inserts the specified flags in-place.
    fn insert(&mut self, other: Self);
    /// Removes the specified flags in-place.
    fn remove(&mut self, other: Self);
    /// Toggles the specified flags in-place.
    fn toggle(&mut self, other: Self);
    /// Inserts or removes the specified flags depending on the passed value.
    fn set(&mut self, other: Self, value: bool);
}
<|endoftext|>


<commit_before>use serde::{Deserialize, Serialize};
use serde_json::Value;
use url::Url;

use crate::{
    PartialResultParams, Range, SymbolKind, SymbolTag, TextDocumentPositionParams,
    WorkDoneProgressOptions, WorkDoneProgressParams,
};

#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOptions {
    #[serde(flatten)]
    pub work_done_progress_options: WorkDoneProgressOptions,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum CallHierarchyServerCapability {
    Simple(bool),
    Options(CallHierarchyOptions),
}

impl From<CallHierarchyOptions> for CallHierarchyServerCapability {
    fn from(from: CallHierarchyOptions) -> Self {
        Self::Options(from)
    }
}

impl From<bool> for CallHierarchyServerCapability {
    fn from(from: bool) -> Self {
        Self::Simple(from)
    }
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyPrepareParams {
    #[serde(flatten)]
    pub text_document_position_params: TextDocumentPositionParams,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyItem {
    /// The name of this item.
    pub name: String,

    /// The kind of this item.
    pub kind: SymbolKind,

    /// Tags for this item.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<SymbolTag>>,

    /// More detail for this item, e.g. the signature of a function.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub detail: Option<String>,

    /// The resource identifier of this item.
    pub uri: Url,

    /// The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code.
    pub range: Range,

    /// The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.
    /// Must be contained by the [`range`](#CallHierarchyItem.range).
    pub selection_range: Range,

    /// A data entry field that is preserved between a call hierarchy prepare and incloming calls or outgoing calls requests.
    pub data: Option<Value>,
}

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCallsParams {
    pub item: CallHierarchyItem,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,

    #[serde(flatten)]
    pub partial_result_params: PartialResultParams,
}

/// Represents an incoming call, e.g. a caller of a method or constructor.
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCall {
    /// The item that makes the call.
    pub from: CallHierarchyItem,

    /// The range at which at which the calls appears. This is relative to the caller
    /// denoted by [`this.from`](#CallHierarchyIncomingCall.from).
    pub from_ranges: Vec<Range>,
}

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCallsParams {
    pub item: CallHierarchyItem,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,

    #[serde(flatten)]
    pub partial_result_params: PartialResultParams,
}

/// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCall {
    /// The item that is called.
    pub to: CallHierarchyItem,

    /// The range at which this item is called. This is the range relative to the caller, e.g the item
    /// passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
    /// and not [`this.to`](#CallHierarchyOutgoingCall.to).
    pub from_ranges: Vec<Range>,
}
<commit_msg>Update src/call_hierarchy.rs<commit_after>use serde::{Deserialize, Serialize};
use serde_json::Value;
use url::Url;

use crate::{
    PartialResultParams, Range, SymbolKind, SymbolTag, TextDocumentPositionParams,
    WorkDoneProgressOptions, WorkDoneProgressParams,
};

#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOptions {
    #[serde(flatten)]
    pub work_done_progress_options: WorkDoneProgressOptions,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum CallHierarchyServerCapability {
    Simple(bool),
    Options(CallHierarchyOptions),
}

impl From<CallHierarchyOptions> for CallHierarchyServerCapability {
    fn from(from: CallHierarchyOptions) -> Self {
        Self::Options(from)
    }
}

impl From<bool> for CallHierarchyServerCapability {
    fn from(from: bool) -> Self {
        Self::Simple(from)
    }
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyPrepareParams {
    #[serde(flatten)]
    pub text_document_position_params: TextDocumentPositionParams,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyItem {
    /// The name of this item.
    pub name: String,

    /// The kind of this item.
    pub kind: SymbolKind,

    /// Tags for this item.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<SymbolTag>>,

    /// More detail for this item, e.g. the signature of a function.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub detail: Option<String>,

    /// The resource identifier of this item.
    pub uri: Url,

    /// The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code.
    pub range: Range,

    /// The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.
    /// Must be contained by the [`range`](#CallHierarchyItem.range).
    pub selection_range: Range,

    /// A data entry field that is preserved between a call hierarchy prepare and incloming calls or outgoing calls requests.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data: Option<Value>,
}

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCallsParams {
    pub item: CallHierarchyItem,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,

    #[serde(flatten)]
    pub partial_result_params: PartialResultParams,
}

/// Represents an incoming call, e.g. a caller of a method or constructor.
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyIncomingCall {
    /// The item that makes the call.
    pub from: CallHierarchyItem,

    /// The range at which at which the calls appears. This is relative to the caller
    /// denoted by [`this.from`](#CallHierarchyIncomingCall.from).
    pub from_ranges: Vec<Range>,
}

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCallsParams {
    pub item: CallHierarchyItem,

    #[serde(flatten)]
    pub work_done_progress_params: WorkDoneProgressParams,

    #[serde(flatten)]
    pub partial_result_params: PartialResultParams,
}

/// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CallHierarchyOutgoingCall {
    /// The item that is called.
    pub to: CallHierarchyItem,

    /// The range at which this item is called. This is the range relative to the caller, e.g the item
    /// passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
    /// and not [`this.to`](#CallHierarchyOutgoingCall.to).
    pub from_ranges: Vec<Range>,
}
<|endoftext|>


<commit_before>use edit::buffer::TextBuffer;
use state::editor::Editor;

impl Editor {
    /// Goto a given position. Does not automatically bound.
    #[inline]
    pub fn goto(&mut self, (x, y): (usize, usize)) {
        self.cursor_mut().y = y;
        self.cursor_mut().x = x;
    }

    /// Get the previous position, i.e. the position before the cursor (*not* left to the cursor).
    /// Includes newline positions.
    #[inline]
    pub fn previous(&self, n: usize) -> Option<(usize, usize)> {
        self.before(n, self.pos())
    }
    /// Get the next position, i.e. the position after the cursor (*not* right to the cursor)
    #[inline]
    pub fn next(&self, n: usize) -> Option<(usize, usize)> {
        self.after(n, self.pos())
    }

    /// Get position after a given position, i.e. a generalisation of .next()
    #[inline]
    pub fn after(&self, n: usize, (x, y): (usize, usize)) -> Option<(usize, usize)> {

        // TODO: Make this more idiomatic {
        if x + n < self.buffers.current_buffer()[y].len() {

            Some((x + n, y))
        } else {
            if y + 1 >= self.buffers.current_buffer().len() {
                None
            } else {
                let mut mv = n + x - self.buffers.current_buffer()[y].len();
                let mut ry = y + 1;

                loop {
                    if mv < self.buffers.current_buffer()[ry].len() {
                        return Some((mv, ry));
                    } else {
                        if ry + 1 < self.buffers.current_buffer().len() {
                            mv -= self.buffers.current_buffer()[ry].len();
                            ry += 1;
                        } else {
                            return None;
                        }
                    }
                }

            }
        }
        // }
    }

    /// Get the position before a given position, i.e. a generalisation .before(). Includes
    /// newline positions.
    #[inline]
    pub fn before(&self, n: usize, (x, y): (usize, usize)) -> Option<(usize, usize)> {
        if x >= n {
            Some((x - n, y))
        } else {
            if y == 0 {
                None
            } else {
                let mut mv = n - x - 1;
                let mut ry = y - 1;

                loop {
                    if mv <= self.buffers.current_buffer()[ry].len() {
                        return Some((self.buffers.current_buffer()[ry].len() - mv, ry));
                    } else {
                        if ry > 0 && mv >= self.buffers.current_buffer()[ry].len() {
                            mv -= self.buffers.current_buffer()[ry].len();
                            ry -= 1;
                        } else if ry == 0 {
                            return None;

                        }
                    }
                }
            }
        }
    }

    /// Get the position of the character right to the cursor (horizontally bounded)
    #[inline]
    pub fn right(&self, n: usize, tight: bool) -> (usize, usize) {
        self.bound_hor((self.x() + n, self.y()), tight)
    }
    /// Get the position of the character right to the cursor (unbounded)
    #[inline]
    pub fn right_unbounded(&self, n: usize) -> (isize, isize) {
        ((self.x() + n) as isize, self.y() as isize)
    }

    /// Get the position of the character left to the cursor (horizontally bounded)
    #[inline]
    pub fn left(&self, n: usize) -> (usize, usize) {
        if n <= self.x() {
            (self.x() - n, self.y())
        } else {
            (0, self.y())
        }
    }
    /// Get the position of the character left to the cursor (unbounded)
    #[inline]
    pub fn left_unbounded(&self, n: usize) -> (isize, isize) {
        (self.x() as isize - n as isize, self.y() as isize)
    }

    /// Get the position of the character above the cursor (vertically bounded)
    #[inline]
    pub fn up(&self, n: usize) -> (usize, usize) {
        if n <= self.y() {
            (self.cursor().x, self.y() - n)
        } else {
            (self.cursor().x, 0)
        }
    }
    /// Get the position of the character above the cursor (unbounded)
    #[inline]
    pub fn up_unbounded(&self, n: usize) -> (isize, isize) {
        (self.cursor().x as isize, self.y() as isize - n as isize)
    }

    /// Get the position of the character under the cursor (vertically bounded)
    #[inline]
    pub fn down(&self, n: usize) -> (usize, usize) {
        self.bound_ver((self.cursor().x, self.y() + n))
    }
    /// Get the position of the character above the cursor (unbounded)
    #[inline]
    pub fn down_unbounded(&self, n: usize) -> (isize, isize) {
        (self.cursor().x as isize, self.y() as isize + n as isize)

    }

    /// Get n'th next ocurrence of a given charecter (relatively to the cursor)
    pub fn next_ocur(&self, c: char, n: usize) -> Option<usize> {
        let mut dn = 0;
        let x      = self.x();

        for ch in self.buffers.current_buffer()[self.y()].chars().skip(x) {
            if dn == n {
                if ch == c {
                    dn += 1;
                    if dn == n {
                        return Some(x);
                    }
                }
            }
        }

        None
    }

    /// Get n'th previous ocurrence of a given charecter (relatively to the cursor)
    pub fn previous_ocur(&self, c: char, n: usize) -> Option<usize> {
        let mut dn = 0;
        let x      = self.x();
        let y      = self.y();

        for ch in self.buffers.current_buffer()[y].chars().rev().skip(self.buffers.current_buffer()[y].len() - x) {
            if dn == n {
                if ch == c {
                    dn += 1;
                    if dn == n {
                        return Some(x);
                    }
                }
            }
        }

        None
    }
}
<commit_msg>removing extraneous if. getting updated position of next occurence<commit_after>use edit::buffer::TextBuffer;
use state::editor::Editor;

impl Editor {
    /// Goto a given position. Does not automatically bound.
    #[inline]
    pub fn goto(&mut self, (x, y): (usize, usize)) {
        self.cursor_mut().y = y;
        self.cursor_mut().x = x;
    }

    /// Get the previous position, i.e. the position before the cursor (*not* left to the cursor).
    /// Includes newline positions.
    #[inline]
    pub fn previous(&self, n: usize) -> Option<(usize, usize)> {
        self.before(n, self.pos())
    }
    /// Get the next position, i.e. the position after the cursor (*not* right to the cursor)
    #[inline]
    pub fn next(&self, n: usize) -> Option<(usize, usize)> {
        self.after(n, self.pos())
    }

    /// Get position after a given position, i.e. a generalisation of .next()
    #[inline]
    pub fn after(&self, n: usize, (x, y): (usize, usize)) -> Option<(usize, usize)> {

        // TODO: Make this more idiomatic {
        if x + n < self.buffers.current_buffer()[y].len() {

            Some((x + n, y))
        } else {
            if y + 1 >= self.buffers.current_buffer().len() {
                None
            } else {
                let mut mv = n + x - self.buffers.current_buffer()[y].len();
                let mut ry = y + 1;

                loop {
                    if mv < self.buffers.current_buffer()[ry].len() {
                        return Some((mv, ry));
                    } else {
                        if ry + 1 < self.buffers.current_buffer().len() {
                            mv -= self.buffers.current_buffer()[ry].len();
                            ry += 1;
                        } else {
                            return None;
                        }
                    }
                }

            }
        }
        // }
    }

    /// Get the position before a given position, i.e. a generalisation .before(). Includes
    /// newline positions.
    #[inline]
    pub fn before(&self, n: usize, (x, y): (usize, usize)) -> Option<(usize, usize)> {
        if x >= n {
            Some((x - n, y))
        } else {
            if y == 0 {
                None
            } else {
                let mut mv = n - x - 1;
                let mut ry = y - 1;

                loop {
                    if mv <= self.buffers.current_buffer()[ry].len() {
                        return Some((self.buffers.current_buffer()[ry].len() - mv, ry));
                    } else {
                        if ry > 0 && mv >= self.buffers.current_buffer()[ry].len() {
                            mv -= self.buffers.current_buffer()[ry].len();
                            ry -= 1;
                        } else if ry == 0 {
                            return None;

                        }
                    }
                }
            }
        }
    }

    /// Get the position of the character right to the cursor (horizontally bounded)
    #[inline]
    pub fn right(&self, n: usize, tight: bool) -> (usize, usize) {
        self.bound_hor((self.x() + n, self.y()), tight)
    }
    /// Get the position of the character right to the cursor (unbounded)
    #[inline]
    pub fn right_unbounded(&self, n: usize) -> (isize, isize) {
        ((self.x() + n) as isize, self.y() as isize)
    }

    /// Get the position of the character left to the cursor (horizontally bounded)
    #[inline]
    pub fn left(&self, n: usize) -> (usize, usize) {
        if n <= self.x() {
            (self.x() - n, self.y())
        } else {
            (0, self.y())
        }
    }
    /// Get the position of the character left to the cursor (unbounded)
    #[inline]
    pub fn left_unbounded(&self, n: usize) -> (isize, isize) {
        (self.x() as isize - n as isize, self.y() as isize)
    }

    /// Get the position of the character above the cursor (vertically bounded)
    #[inline]
    pub fn up(&self, n: usize) -> (usize, usize) {
        if n <= self.y() {
            (self.cursor().x, self.y() - n)
        } else {
            (self.cursor().x, 0)
        }
    }
    /// Get the position of the character above the cursor (unbounded)
    #[inline]
    pub fn up_unbounded(&self, n: usize) -> (isize, isize) {
        (self.cursor().x as isize, self.y() as isize - n as isize)
    }

    /// Get the position of the character under the cursor (vertically bounded)
    #[inline]
    pub fn down(&self, n: usize) -> (usize, usize) {
        self.bound_ver((self.cursor().x, self.y() + n))
    }
    /// Get the position of the character above the cursor (unbounded)
    #[inline]
    pub fn down_unbounded(&self, n: usize) -> (isize, isize) {
        (self.cursor().x as isize, self.y() as isize + n as isize)

    }

    /// Get n'th next ocurrence of a given charecter (relatively to the cursor)
    pub fn next_ocur(&self, c: char, n: usize) -> Option<usize> {
        let mut dn = 0;
        let mut x      = self.x();

        for (i, ch) in self.buffers.current_buffer()[self.y()].chars().skip(x).enumerate() {
            if ch == c {
                dn += 1;
                if dn == n {
                    x += i;
                    return Some(x);
                }
            }
        }

        None
    }

    /// Get n'th previous ocurrence of a given charecter (relatively to the cursor)
    pub fn previous_ocur(&self, c: char, n: usize) -> Option<usize> {
        let mut dn = 0;
        let x      = self.x();
        let y      = self.y();

        for ch in self.buffers.current_buffer()[y].chars().rev().skip(self.buffers.current_buffer()[y].len() - x) {
            if dn == n {
                if ch == c {
                    dn += 1;
                    if dn == n {
                        return Some(x);
                    }
                }
            }
        }

        None
    }
}
<|endoftext|>


<commit_before>use crate::util::CargoResult;
use cargo_util::paths;
use cargo_util::ProcessBuilder;
use std::path::Path;

// Check if we are in an existing repo. We define that to be true if either:
//
// 1. We are in a git repo and the path to the new package is not an ignored
//    path in that repo.
// 2. We are in an HG repo.
pub fn existing_vcs_repo(path: &Path, cwd: &Path) -> bool {
    fn in_git_repo(path: &Path, cwd: &Path) -> bool {
        if let Ok(repo) = GitRepo::discover(path, cwd) {
            // Don't check if the working directory itself is ignored.
            if repo.workdir().map_or(false, |workdir| workdir == path) {
                true
            } else {
                !repo.is_path_ignored(path).unwrap_or(false)
            }
        } else {
            false
        }
    }

    in_git_repo(path, cwd) || HgRepo::discover(path, cwd).is_ok()
}

pub struct HgRepo;
pub struct GitRepo;
pub struct PijulRepo;
pub struct FossilRepo;

impl GitRepo {
    pub fn init(path: &Path, _: &Path) -> CargoResult<GitRepo> {
        git2::Repository::init(path)?;
        Ok(GitRepo)
    }
    pub fn discover(path: &Path, _: &Path) -> Result<git2::Repository, git2::Error> {
        git2::Repository::discover(path)
    }
}

impl HgRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<HgRepo> {
        ProcessBuilder::new("hg")
            .cwd(cwd)
            .arg("init")
            .arg(path)
            .exec()?;
        Ok(HgRepo)
    }
    pub fn discover(path: &Path, cwd: &Path) -> CargoResult<HgRepo> {
        ProcessBuilder::new("hg")
            .cwd(cwd)
            .arg("--cwd")
            .arg(path)
            .arg("root")
            .exec_with_output()?;
        Ok(HgRepo)
    }
}

impl PijulRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<PijulRepo> {
        ProcessBuilder::new("pijul")
            .cwd(cwd)
            .arg("init")
            .arg(path)
            .exec()?;
        Ok(PijulRepo)
    }
}

impl FossilRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<FossilRepo> {
        // fossil doesn't create the directory so we'll do that first
        paths::create_dir_all(path)?;

        // set up the paths we'll use
        let db_fname = ".fossil";
        let mut db_path = path.to_owned();
        db_path.push(db_fname);

        // then create the fossil DB in that location
        ProcessBuilder::new("fossil")
            .cwd(cwd)
            .arg("init")
            .arg(&db_path)
            .exec()?;

        // open it in that new directory
        ProcessBuilder::new("fossil")
            .cwd(&path)
            .arg("open")
            .arg(db_fname)
            .exec()?;

        Ok(FossilRepo)
    }
}
<commit_msg>Auto merge of #10483 - cuviper:vcs--, r=Eh2406<commit_after>use crate::util::CargoResult;
use cargo_util::paths;
use cargo_util::ProcessBuilder;
use std::path::Path;

// Check if we are in an existing repo. We define that to be true if either:
//
// 1. We are in a git repo and the path to the new package is not an ignored
//    path in that repo.
// 2. We are in an HG repo.
pub fn existing_vcs_repo(path: &Path, cwd: &Path) -> bool {
    fn in_git_repo(path: &Path, cwd: &Path) -> bool {
        if let Ok(repo) = GitRepo::discover(path, cwd) {
            // Don't check if the working directory itself is ignored.
            if repo.workdir().map_or(false, |workdir| workdir == path) {
                true
            } else {
                !repo.is_path_ignored(path).unwrap_or(false)
            }
        } else {
            false
        }
    }

    in_git_repo(path, cwd) || HgRepo::discover(path, cwd).is_ok()
}

pub struct HgRepo;
pub struct GitRepo;
pub struct PijulRepo;
pub struct FossilRepo;

impl GitRepo {
    pub fn init(path: &Path, _: &Path) -> CargoResult<GitRepo> {
        git2::Repository::init(path)?;
        Ok(GitRepo)
    }
    pub fn discover(path: &Path, _: &Path) -> Result<git2::Repository, git2::Error> {
        git2::Repository::discover(path)
    }
}

impl HgRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<HgRepo> {
        ProcessBuilder::new("hg")
            .cwd(cwd)
            .arg("init")
            .arg("--")
            .arg(path)
            .exec()?;
        Ok(HgRepo)
    }
    pub fn discover(path: &Path, cwd: &Path) -> CargoResult<HgRepo> {
        ProcessBuilder::new("hg")
            .cwd(cwd)
            .arg("--cwd")
            .arg(path)
            .arg("root")
            .exec_with_output()?;
        Ok(HgRepo)
    }
}

impl PijulRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<PijulRepo> {
        ProcessBuilder::new("pijul")
            .cwd(cwd)
            .arg("init")
            .arg("--")
            .arg(path)
            .exec()?;
        Ok(PijulRepo)
    }
}

impl FossilRepo {
    pub fn init(path: &Path, cwd: &Path) -> CargoResult<FossilRepo> {
        // fossil doesn't create the directory so we'll do that first
        paths::create_dir_all(path)?;

        // set up the paths we'll use
        let db_fname = ".fossil";
        let mut db_path = path.to_owned();
        db_path.push(db_fname);

        // then create the fossil DB in that location
        ProcessBuilder::new("fossil")
            .cwd(cwd)
            .arg("init")
            .arg("--")
            .arg(&db_path)
            .exec()?;

        // open it in that new directory
        ProcessBuilder::new("fossil")
            .cwd(&path)
            .arg("open")
            .arg("--")
            .arg(db_fname)
            .exec()?;

        Ok(FossilRepo)
    }
}
<|endoftext|>


<commit_before>use crate::printing;

pub fn next() {
    printing::heading("Follow feeds so that I'm aware of industry changes.");

    printing::subheading("Open the top recent items in each feed");

    printing::subheading("Programming");
    printing::list(vec!["https://www.reddit.com/r/programming/top/?t=month"]);

    printing::subheading("Unix");
    printing::list(vec![
        "https://brew.sh/blog",
        "https://www.reddit.com/r/commandline/top/?t=month",
    ]);

    printing::subheading("Vim");
    printing::list(vec![
        "https://www.vim.org/news/news.php",
        "https://www.reddit.com/r/vim/top/?t=month",
    ]);

    printing::subheading("Git");
    printing::list(vec!["https://www.reddit.com/r/git/top/?t=month"]);

    printing::subheading("Rust");
    printing::list(vec![
        "https://blog.rust-lang.org",
        "https://www.reddit.com/r/rust/top/?t=month",
    ]);

    printing::subheading("JavaScript");
    printing::list(vec!["https://www.reddit.com/r/javascript/top/?t=month"]);
    printing::list(vec!["https://nodejs.org/en/blog/"]);
    printing::list(vec!["https://www.reddit.com/r/node/top/?t=month"]);
    printing::list(vec!["https://reactjs.org/blog/all.html"]);
    printing::list(vec!["https://nextjs.org/blog"]);

    printing::pause();
}
<commit_msg>Add github trends to feeds<commit_after>use crate::printing;

pub fn next() {
    printing::heading("Follow feeds so that I'm aware of industry changes.");

    printing::subheading("Open the top recent items in each feed");

    printing::subheading("Programming");
    printing::list(vec![
        "https://www.reddit.com/r/programming/top/?t=month",
        "https://github.com/trending?since=monthly"
    ]);

    printing::subheading("Unix");
    printing::list(vec![
        "https://brew.sh/blog",
        "https://www.reddit.com/r/commandline/top/?t=month",
    ]);

    printing::subheading("Vim");
    printing::list(vec![
        "https://www.vim.org/news/news.php",
        "https://www.reddit.com/r/vim/top/?t=month",
    ]);

    printing::subheading("Git");
    printing::list(vec!["https://www.reddit.com/r/git/top/?t=month"]);

    printing::subheading("Rust");
    printing::list(vec![
        "https://blog.rust-lang.org",
        "https://www.reddit.com/r/rust/top/?t=month",
    ]);

    printing::subheading("JavaScript");
    printing::list(vec!["https://www.reddit.com/r/javascript/top/?t=month"]);
    printing::list(vec!["https://nodejs.org/en/blog/"]);
    printing::list(vec!["https://www.reddit.com/r/node/top/?t=month"]);
    printing::list(vec!["https://reactjs.org/blog/all.html"]);
    printing::list(vec!["https://nextjs.org/blog"]);

    printing::pause();
}
<|endoftext|>


<commit_before>

use sync::Arc;
use waitstrategy::{WaitStrategy};
use paddedatomics::Padded64;
use ringbuffer::{RingBuffer, Slot};

/// EventProcessors provide functionality to process and consume data from the ring buffer
pub struct EventProcessor<T> {
    graph: Arc<Vec<Vec<uint>>>,
    cursors: Arc<Vec<Padded64>>,
    token: uint,
    ring: Arc<RingBuffer<T>>
}

impl<T: Slot> EventProcessor<T> {

    /// Instantiate a new EventProcessor.
    ///
    /// This accepts several important parameters and is for internal use only.
    /// - ring: an instance of the ring buffer
    /// - graph: a dependency graph, showing how all the EPs relate to eachother.
    /// - cursors: a vector of Padded64 atomics which act as cursors into the ring buffer
    /// - token: the index in the graph which represents this EP
    pub fn new(ring: Arc<RingBuffer<T>>, graph: Arc<Vec<Vec<uint>>>, cursors: Arc<Vec<Padded64>>, token: uint) -> EventProcessor<T> {
        EventProcessor::<T> {
            graph: graph,
            cursors: cursors,
            token: token,
            ring: ring
        }
    }

    /// Begin waiting for data to arrive from the ring buffer.
    ///
    /// This method is the only "public" method in EventProcessor.rs.
    /// This method accepts a closure as its only parameter.  Once data is received (e.g. all dependencies have been
    /// satisfied and the data is ready to be consumed), this closure is called.  A slice from the ring buffer is passed
    /// to the closure.
    ///
    /// The slice may containe one or more pieces of data to process (this batching adds a lot of performance to Turbine).
    /// The user-code running inside the closure must be capable of handling multiple pieces of data.
    ///
    /// Upon completion of processing the data, the closure must return a Result signaling if it wants the event processor
    /// to continue running, or exit.  A Result of Ok(()) will tell the EP to continue running.  A Result of Err(()) will
    /// shut down the EP.
    ///
    /// ## Example
    ///
    ///```
    ///spawn(proc() {
    ///     event_processor.start::<BusyWait>(|data: &[TestSlot]| -> Result<(),()> {
    ///         assert!(data.len() == 1);
    ///         assert!(data[0].value == 19);
    ///         return Ok(());
    ///     });
    ///});
    ///```
    pub fn start<W: WaitStrategy>(&self, f: |data: &[T]| -> Result<(),()>) {
        let capacity = self.ring.get_capacity();

        let wait_strategy: W = WaitStrategy::new(capacity);

        let dep_eps = self.graph.get(self.token);
        let mut deps: Vec<&Padded64> = Vec::with_capacity(dep_eps.len());
        for ep in dep_eps.iter() {
            deps.push((*self.cursors).get(*ep));
        }
        drop(dep_eps);

        let cursor = (*self.cursors).get(self.token + 1);

        let mask: u64 = capacity as u64 - 1;
        let mut internal_cursor = cursor.load();
        let mut rollover = (false, 0);

        loop {
            debug!("              Current: {}, waiting on: {}", internal_cursor, internal_cursor);

            let available = wait_strategy.wait_for(internal_cursor, &deps);
            debug!("							Available: {}", available);

            let from = (internal_cursor & mask) as uint;
            let mut to = (available & mask) as uint;

            debug!("              from: {}, to: {} -- {}", from, to, (to < from));
            if to < from {
                debug!("						ROLLOVER");
                rollover = (true, to);
                to = capacity;
            } else if (to == from) && (internal_cursor < available) {
                //complete buffer request
                debug!("						ROLLOVER (total) -- ({} == {}) && ({} < {})", to, from, internal_cursor, available);
                rollover = (true, to);
                to = capacity;
            } else if (to == from) {
                debug!("						WTF to == from    -- ({} == {}) && ({} < {})", to, from, internal_cursor, available);
            }

            debug!("              Post-modification from: {}, to: {} -- {}", from, to, (to < from));

            // This is safe because the Producer task cannot invalidate these slots
            // before we increment our cursor.  Since the slice is borrowed out, we
            // know it will be returned after the function call ends.  The slice will
            // be dropped after the unsafe block, and *then* we increment our cursor
            let mut status = unsafe {
                let data: &[T] = self.ring.get(from, to);
                f(data)
            };

            if rollover.val0() == true {
                debug!("ROlLOVER GET");
                status = unsafe {
                    let data: &[T] = self.ring.get(0, rollover.val1());
                    f(data)
                };
                rollover = (false,0);
            }

            internal_cursor = available;
            cursor.store(internal_cursor);
            debug!("					Finished processing event.  Cursor @ {} ({})", available, available & mask);

            match status {
                Err(_) => break,
                Ok(_) => {}
            };

        }
        debug!("BusyWait::end");
    }
}
<commit_msg>Use vector indexing notation<commit_after>

use sync::Arc;
use waitstrategy::{WaitStrategy};
use paddedatomics::Padded64;
use ringbuffer::{RingBuffer, Slot};

/// EventProcessors provide functionality to process and consume data from the ring buffer
pub struct EventProcessor<T> {
    graph: Arc<Vec<Vec<uint>>>,
    cursors: Arc<Vec<Padded64>>,
    token: uint,
    ring: Arc<RingBuffer<T>>
}

impl<T: Slot> EventProcessor<T> {

    /// Instantiate a new EventProcessor.
    ///
    /// This accepts several important parameters and is for internal use only.
    /// - ring: an instance of the ring buffer
    /// - graph: a dependency graph, showing how all the EPs relate to eachother.
    /// - cursors: a vector of Padded64 atomics which act as cursors into the ring buffer
    /// - token: the index in the graph which represents this EP
    pub fn new(ring: Arc<RingBuffer<T>>, graph: Arc<Vec<Vec<uint>>>, cursors: Arc<Vec<Padded64>>, token: uint) -> EventProcessor<T> {
        EventProcessor::<T> {
            graph: graph,
            cursors: cursors,
            token: token,
            ring: ring
        }
    }

    /// Begin waiting for data to arrive from the ring buffer.
    ///
    /// This method is the only "public" method in EventProcessor.rs.
    /// This method accepts a closure as its only parameter.  Once data is received (e.g. all dependencies have been
    /// satisfied and the data is ready to be consumed), this closure is called.  A slice from the ring buffer is passed
    /// to the closure.
    ///
    /// The slice may containe one or more pieces of data to process (this batching adds a lot of performance to Turbine).
    /// The user-code running inside the closure must be capable of handling multiple pieces of data.
    ///
    /// Upon completion of processing the data, the closure must return a Result signaling if it wants the event processor
    /// to continue running, or exit.  A Result of Ok(()) will tell the EP to continue running.  A Result of Err(()) will
    /// shut down the EP.
    ///
    /// ## Example
    ///
    ///```
    ///spawn(proc() {
    ///     event_processor.start::<BusyWait>(|data: &[TestSlot]| -> Result<(),()> {
    ///         assert!(data.len() == 1);
    ///         assert!(data[0].value == 19);
    ///         return Ok(());
    ///     });
    ///});
    ///```
    pub fn start<W: WaitStrategy>(&self, f: |data: &[T]| -> Result<(),()>) {
        let capacity = self.ring.get_capacity();

        let wait_strategy: W = WaitStrategy::new(capacity);

        let ref dep_eps = self.graph.as_slice()[self.token];
        let mut deps: Vec<&Padded64> = Vec::with_capacity(dep_eps.len());
        for ep in dep_eps.iter() {
            deps.push(&(*self.cursors).as_slice()[*ep]);
        }
        drop(dep_eps);

        let ref cursor = &(*self.cursors).as_slice()[self.token + 1];

        let mask: u64 = capacity as u64 - 1;
        let mut internal_cursor = cursor.load();
        let mut rollover = (false, 0);

        loop {
            debug!("              Current: {}, waiting on: {}", internal_cursor, internal_cursor);

            let available = wait_strategy.wait_for(internal_cursor, &deps);
            debug!("							Available: {}", available);

            let from = (internal_cursor & mask) as uint;
            let mut to = (available & mask) as uint;

            debug!("              from: {}, to: {} -- {}", from, to, (to < from));
            if to < from {
                debug!("						ROLLOVER");
                rollover = (true, to);
                to = capacity;
            } else if (to == from) && (internal_cursor < available) {
                //complete buffer request
                debug!("						ROLLOVER (total) -- ({} == {}) && ({} < {})", to, from, internal_cursor, available);
                rollover = (true, to);
                to = capacity;
            } else if (to == from) {
                debug!("						WTF to == from    -- ({} == {}) && ({} < {})", to, from, internal_cursor, available);
            }

            debug!("              Post-modification from: {}, to: {} -- {}", from, to, (to < from));

            // This is safe because the Producer task cannot invalidate these slots
            // before we increment our cursor.  Since the slice is borrowed out, we
            // know it will be returned after the function call ends.  The slice will
            // be dropped after the unsafe block, and *then* we increment our cursor
            let mut status = unsafe {
                let data: &[T] = self.ring.get(from, to);
                f(data)
            };

            if rollover.val0() == true {
                debug!("ROlLOVER GET");
                status = unsafe {
                    let data: &[T] = self.ring.get(0, rollover.val1());
                    f(data)
                };
                rollover = (false,0);
            }

            internal_cursor = available;
            cursor.store(internal_cursor);
            debug!("					Finished processing event.  Cursor @ {} ({})", available, available & mask);

            match status {
                Err(_) => break,
                Ok(_) => {}
            };

        }
        debug!("BusyWait::end");
    }
}
<|endoftext|>


<commit_before>//! Definition of the `LoopFn` combinator, implementing `Future` loops.

use {Async, Future, IntoFuture, Poll};

/// The status of a `loop_fn` loop.
pub enum Loop<T, S> {
    /// Indicates that the loop has completed with output `T`.
    Break(T),

    /// Indicates that the loop function should be called again with input
    /// state `S`.
    Continue(S),
}

/// A future implementing a tail-recursive loop.
///
/// Created by the `loop_fn` function.
pub struct LoopFn<A, F> {
    future: A,
    func: F,
}

/// Creates a new future implementing a tail-recursive loop.
///
/// The loop function is immediately called with `initial_state` and should
/// return a value that can be converted to a future. On successful completion,
/// this future should output a `Loop<T, S>` to indicate the status of the
/// loop.
///
/// `Loop::Break(T)` halts the loop and completes the future with output `T`.
///
/// `Loop::Continue(S)` reinvokes the loop function with state `S`. The returned
/// future will be subsequently polled for a new `Loop<T, S>` value.
///
/// # Examples
///
/// ```
/// use futures::future::{ok, loop_fn, Future, Ok, Loop};
/// use std::io::Error;
///
/// struct Client {
///     ping_count: u8,
/// }
///
/// impl Client {
///     fn new() -> Self {
///         Client { ping_count: 0 }
///     }
///
///     fn send_ping(self) -> Ok<Self, Error> {
///         ok(Client { ping_count: self.ping_count + 1 })
///     }
///
///     fn receive_pong(self) -> Ok<(Self, bool), Error> {
///         let done = self.ping_count >= 5;
///         ok((self, done))
///     }
/// }
///
/// let ping_til_done = loop_fn(Client::new(), |client| {
///     client.send_ping()
///         .and_then(|client| client.receive_pong())
///         .and_then(|(client, done)| {
///             if done {
///                 Ok(Loop::Break(client))
///             } else {
///                 Ok(Loop::Continue(client))
///             }
///         })
/// });
/// ```
pub fn loop_fn<S, T, I, A, F>(initial_state: S, mut func: F) -> LoopFn<A, F>
    where F: FnMut(S) -> I,
          A: Future<Item = Loop<T, S>>,
          I: IntoFuture<Future = A, Item = A::Item, Error = A::Error>
{
    LoopFn {
        future: func(initial_state).into_future(),
        func: func,
    }
}

impl<S, T, I, A, F> Future for LoopFn<A, F>
    where F: FnMut(S) -> I,
          A: Future<Item = Loop<T, S>>,
          I: IntoFuture<Future = A, Item = A::Item, Error = A::Error>
{
    type Item = T;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            let status = try_ready!(self.future.poll());
            match status {
                Loop::Break(x) => return Ok(Async::Ready(x)),
                Loop::Continue(s) => self.future = (self.func)(s).into_future(),
            }
        }
    }
}
<commit_msg>Tweak loop_fn function bounds<commit_after>//! Definition of the `LoopFn` combinator, implementing `Future` loops.

use {Async, Future, IntoFuture, Poll};

/// The status of a `loop_fn` loop.
pub enum Loop<T, S> {
    /// Indicates that the loop has completed with output `T`.
    Break(T),

    /// Indicates that the loop function should be called again with input
    /// state `S`.
    Continue(S),
}

/// A future implementing a tail-recursive loop.
///
/// Created by the `loop_fn` function.
pub struct LoopFn<A, F> where A: IntoFuture {
    future: A::Future,
    func: F,
}

/// Creates a new future implementing a tail-recursive loop.
///
/// The loop function is immediately called with `initial_state` and should
/// return a value that can be converted to a future. On successful completion,
/// this future should output a `Loop<T, S>` to indicate the status of the
/// loop.
///
/// `Loop::Break(T)` halts the loop and completes the future with output `T`.
///
/// `Loop::Continue(S)` reinvokes the loop function with state `S`. The returned
/// future will be subsequently polled for a new `Loop<T, S>` value.
///
/// # Examples
///
/// ```
/// use futures::future::{ok, loop_fn, Future, Ok, Loop};
/// use std::io::Error;
///
/// struct Client {
///     ping_count: u8,
/// }
///
/// impl Client {
///     fn new() -> Self {
///         Client { ping_count: 0 }
///     }
///
///     fn send_ping(self) -> Ok<Self, Error> {
///         ok(Client { ping_count: self.ping_count + 1 })
///     }
///
///     fn receive_pong(self) -> Ok<(Self, bool), Error> {
///         let done = self.ping_count >= 5;
///         ok((self, done))
///     }
/// }
///
/// let ping_til_done = loop_fn(Client::new(), |client| {
///     client.send_ping()
///         .and_then(|client| client.receive_pong())
///         .and_then(|(client, done)| {
///             if done {
///                 Ok(Loop::Break(client))
///             } else {
///                 Ok(Loop::Continue(client))
///             }
///         })
/// });
/// ```
pub fn loop_fn<S, T, A, F>(initial_state: S, mut func: F) -> LoopFn<A, F>
    where F: FnMut(S) -> A,
          A: IntoFuture<Item = Loop<T, S>>,
{
    LoopFn {
        future: func(initial_state).into_future(),
        func: func,
    }
}

impl<S, T, A, F> Future for LoopFn<A, F>
    where F: FnMut(S) -> A,
          A: IntoFuture<Item = Loop<T, S>>,
{
    type Item = T;
    type Error = A::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            match try_ready!(self.future.poll()) {
                Loop::Break(x) => return Ok(Async::Ready(x)),
                Loop::Continue(s) => self.future = (self.func)(s).into_future(),
            }
        }
    }
}
<|endoftext|>