<commit_before>//! The dump module contains code related for outputing/dumping data.
use std::fmt::Display;

/// Enum which provides all possible output value formats supported by the dump module.
#[derive(Debug)]
pub enum OutputFormat {
    Hex,
    Decimal,
    Octal,
}

/// The OutputLine struct contains all  information needed to dump/output a single line of data.
#[derive(Debug)]
pub struct OutputLine<'a> {
    start_address: u32,
    data: &'a [u8], // TODO NiCo: Add member for data format (output format of data)
    group_size: usize,
    columns: usize,
    output_fmt: OutputFormat,
}

impl<'a> OutputLine<'a> {
    fn new(data: &[u8]) -> OutputLine {
        OutputLine {
            start_address: 0,
            data: data,
            group_size: 1,
            columns: 8,
            output_fmt: OutputFormat::Hex,
        }
    }

    pub fn format(self, fmt: OutputFormat) -> Self {
        OutputLine {
            start_address: self.start_address,
            data: self.data,
            group_size: self.group_size,
            columns: self.columns,
            output_fmt: fmt,
        }
    }

    fn write_formated_byte(&self, f: &mut ::fmt::Formatter, byte: &u8) -> ::fmt::Result {
        match self.output_fmt {
            OutputFormat::Hex => write!(f, "{:02.X}", byte),
            OutputFormat::Octal => write!(f, "{:02.o}", byte),
            OutputFormat::Decimal => write!(f, "{:02}", byte),
        }
    }
}

impl<'a> ::fmt::Display for OutputLine<'a> {
    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
        write!(f, "{:08.X}: ", self.start_address);
        let mut byte_count = 0;
        for b in self.data.iter() {
            byte_count += 1;
            let is_seperator_necessary = byte_count % self.group_size == 0;
            if is_seperator_necessary {
                self.write_formated_byte(f, b);
                write!(f, " ");
            } else {
                self.write_formated_byte(f, b);
            }
        }
        write!(f, "   ........");
        Ok(())
    }
}

mod test {
    use super::*;
    use std::fmt::Write;

    #[test]
    fn outputline_can_be_constructed() {
        let data = [1, 2, 3];
        let output_line = OutputLine::new(&data);
        assert!(true);
    }

    #[test]
    fn default_output_format_for_a_single_line() {
        let data = [1, 2, 3, 4, 5, 6, 7, 8];
        let expected_output = "00000000: 01 02 03 04 05 06 07 08    ........";
        let output_line = OutputLine::new(&data);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }

    #[test]
    fn octal_output_format_on_a_single_line() {
        let data = [8, 9, 10, 11, 12, 13, 14, 15];
        let expected_output = "00000000: 10 11 12 13 14 15 16 17    ........";
        let output_line = OutputLine::new(&data).format(OutputFormat::Octal);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }
}
<commit_msg>Add show interpretation and show address flags<commit_after>//! The dump module contains code related for outputing/dumping data.
use std::fmt::Display;

/// Enum which provides all possible output value formats supported by the dump module.
#[derive(Debug)]
pub enum OutputFormat {
    Hex,
    Decimal,
    Octal,
    Binary,
}

/// The OutputLine struct contains all  information needed to dump/output a single line of data.
#[derive(Debug)]
pub struct OutputLine<'a> {
    start_address: u32,
    show_address: bool,
    data: &'a [u8], // TODO NiCo: Add member for data format (output format of data)
    group_size: usize,
    columns: usize,
    show_interpretation: bool,
    output_fmt: OutputFormat,
}

impl<'a> OutputLine<'a> {
    fn new(data: &[u8]) -> OutputLine {
        OutputLine {
            start_address: 0,
            show_address: true,
            data: data,
            group_size: 1,
            columns: 8,
            show_interpretation: true,
            output_fmt: OutputFormat::Hex,
        }
    }

    pub fn format(self, fmt: OutputFormat) -> Self {
        OutputLine {
            start_address: self.start_address,
            show_address: self.show_interpretation,
            data: self.data,
            group_size: self.group_size,
            columns: self.columns,
            show_interpretation: self.show_interpretation,
            output_fmt: fmt,
        }
    }

    fn write_address(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
        write!(f, "{:08.X}: ", self.start_address)
    }

    fn write_bytes(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
        let mut byte_count = 0;
        for b in self.data.iter() {
            byte_count += 1;
            let is_seperator_necessary = byte_count % self.group_size == 0;
            if is_seperator_necessary {
                self.write_formated_byte(f, b)?;
                write!(f, " ")?
            } else {
                self.write_formated_byte(f, b)?
            }
        }
        Ok(())
    }

    fn write_formated_byte(&self, f: &mut ::fmt::Formatter, byte: &u8) -> ::fmt::Result {
        match self.output_fmt {
            OutputFormat::Hex => write!(f, "{:02.X}", byte),
            OutputFormat::Octal => write!(f, "{:02.o}", byte),
            OutputFormat::Decimal => write!(f, "{:02}", byte),
            OutputFormat::Binary => write!(f, "{:02b}", byte),
        }
    }

    fn write_interpretation(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
        write!(f, "   ");
        for b in self.data.iter() {
            match *b {
                character @ 20u8...126u8 => write!(f, "{}", character as char)?,
                _ => write!(f, "{}", ".")?,
            }
        }
        Ok(())
    }
}

impl<'a> ::fmt::Display for OutputLine<'a> {
    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
        if self.show_address {
            self.write_address(f);
        }
        self.write_bytes(f);
        if self.show_interpretation {
            self.write_interpretation(f);
        }
        Ok(())
    }
}

mod test {
    use super::*;
    use std::fmt::Write;

    #[test]
    fn outputline_can_be_constructed() {
        let data = [1, 2, 3];
        let output_line = OutputLine::new(&data);
        assert!(true);
    }

    #[test]
    fn default_output_format_for_a_single_line() {
        let data = [1, 2, 3, 4, 5, 6, 7, 8];
        let expected_output = "00000000: 01 02 03 04 05 06 07 08    ........";
        let output_line = OutputLine::new(&data);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }

    #[test]
    fn octal_output_format_on_a_single_line() {
        let data = [8, 9, 10, 11, 12, 13, 14, 15];
        let expected_output = "00000000: 10 11 12 13 14 15 16 17    ........";
        let output_line = OutputLine::new(&data).format(OutputFormat::Octal);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }

    #[test]
    fn binary_output_format_on_a_single_line() {
        let data = [65, 66, 67, 68, 126, 124, 60, 46];
        let expected_output = "00000000: 1000001 1000010 1000011 1000100 1111110 1111100 111100 101110    ABCD~|<.";
        let output_line = OutputLine::new(&data).format(OutputFormat::Binary);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }

    #[test]
    fn interpretation_for_default_settings() {
        let data = [65, 66, 67, 68, 126, 124, 60, 46];
        let expected_output = "00000000: 41 42 43 44 7E 7C 3C 2E    ABCD~|<.";
        let output_line = OutputLine::new(&data);
        let mut buffer = String::new();
        let result = write!(&mut buffer, "{}", output_line);
        assert_eq!(Ok(()), result);
        assert_eq!(expected_output, buffer);
    }
}
<|endoftext|>


<commit_before>use crate::syntax::atom::Atom::{self, *};
use crate::syntax::report::Errors;
use crate::syntax::set::OrderedSet as Set;
use crate::syntax::{Api, Derive, Enum, Struct, Type, TypeAlias};
use proc_macro2::Ident;
use quote::ToTokens;
use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};

pub struct Types<'a> {
    pub all: Set<'a, Type>,
    pub structs: Map<Ident, &'a Struct>,
    pub enums: Map<Ident, &'a Enum>,
    pub cxx: Set<'a, Ident>,
    pub rust: Set<'a, Ident>,
    pub aliases: Map<Ident, &'a TypeAlias>,
}

impl<'a> Types<'a> {
    pub fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {
        let mut all = Set::new();
        let mut structs = Map::new();
        let mut enums = Map::new();
        let mut cxx = Set::new();
        let mut rust = Set::new();
        let mut aliases = Map::new();

        fn visit<'a>(all: &mut Set<'a, Type>, ty: &'a Type) {
            all.insert(ty);
            match ty {
                Type::Ident(_) | Type::Str(_) | Type::Void(_) | Type::SliceRefU8(_) => {}
                Type::RustBox(ty)
                | Type::UniquePtr(ty)
                | Type::CxxVector(ty)
                | Type::RustVec(ty) => visit(all, &ty.inner),
                Type::Ref(r) => visit(all, &r.inner),
                Type::Slice(s) => visit(all, &s.inner),
                Type::Fn(f) => {
                    if let Some(ret) = &f.ret {
                        visit(all, ret);
                    }
                    for arg in &f.args {
                        visit(all, &arg.ty);
                    }
                }
            }
        }

        let mut type_names = UnorderedSet::new();
        let mut function_names = UnorderedSet::new();
        for api in apis {
            match api {
                Api::Include(_) => {}
                Api::Struct(strct) => {
                    let ident = &strct.ident;
                    if type_names.insert(ident) {
                        structs.insert(ident.clone(), strct);
                    } else {
                        duplicate_name(cx, strct, ident);
                    }
                    for field in &strct.fields {
                        visit(&mut all, &field.ty);
                    }
                }
                Api::Enum(enm) => {
                    let ident = &enm.ident;
                    // We allow declaring the same type as a shared enum and as a Cxxtype, as this
                    // means not to emit the C++ enum definition.
                    if !type_names.insert(ident) && !cxx.contains(ident) {
                        duplicate_name(cx, enm, ident);
                    }
                    enums.insert(ident.clone(), enm);
                }
                Api::CxxType(ety) => {
                    let ident = &ety.ident;
                    // We allow declaring the same type as a shared enum and as a Cxxtype, as this
                    // means not to emit the C++ enum definition.
                    if !type_names.insert(ident) && !enums.contains_key(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    cxx.insert(ident);
                }
                Api::RustType(ety) => {
                    let ident = &ety.ident;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    rust.insert(ident);
                }
                Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                    let ident = &efn.ident;
                    if !function_names.insert((&efn.receiver, ident)) {
                        duplicate_name(cx, efn, ident);
                    }
                    for arg in &efn.args {
                        visit(&mut all, &arg.ty);
                    }
                    if let Some(ret) = &efn.ret {
                        visit(&mut all, ret);
                    }
                }
                Api::TypeAlias(alias) => {
                    let ident = &alias.ident;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, alias, ident);
                    }
                    cxx.insert(ident);
                    aliases.insert(ident.clone(), alias);
                }
            }
        }

        Types {
            all,
            structs,
            enums,
            cxx,
            rust,
            aliases,
        }
    }

    pub fn needs_indirect_abi(&self, ty: &Type) -> bool {
        match ty {
            Type::Ident(ident) => {
                if let Some(strct) = self.structs.get(ident) {
                    !self.is_pod(strct)
                } else {
                    Atom::from(ident) == Some(RustString)
                }
            }
            Type::RustVec(_) => true,
            _ => false,
        }
    }

    pub fn is_pod(&self, strct: &Struct) -> bool {
        for derive in &strct.derives {
            if *derive == Derive::Copy {
                return true;
            }
        }
        false
    }
}

impl<'t, 'a> IntoIterator for &'t Types<'a> {
    type Item = &'a Type;
    type IntoIter = crate::syntax::set::Iter<'t, 'a, Type>;
    fn into_iter(self) -> Self::IntoIter {
        self.all.into_iter()
    }
}

fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
    let msg = format!("the name `{}` is defined multiple times", ident);
    cx.error(sp, msg);
}
<commit_msg>Clean up some unneeded clones of the type names<commit_after>use crate::syntax::atom::Atom::{self, *};
use crate::syntax::report::Errors;
use crate::syntax::set::OrderedSet as Set;
use crate::syntax::{Api, Derive, Enum, Struct, Type, TypeAlias};
use proc_macro2::Ident;
use quote::ToTokens;
use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};

pub struct Types<'a> {
    pub all: Set<'a, Type>,
    pub structs: Map<&'a Ident, &'a Struct>,
    pub enums: Map<&'a Ident, &'a Enum>,
    pub cxx: Set<'a, Ident>,
    pub rust: Set<'a, Ident>,
    pub aliases: Map<&'a Ident, &'a TypeAlias>,
}

impl<'a> Types<'a> {
    pub fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {
        let mut all = Set::new();
        let mut structs = Map::new();
        let mut enums = Map::new();
        let mut cxx = Set::new();
        let mut rust = Set::new();
        let mut aliases = Map::new();

        fn visit<'a>(all: &mut Set<'a, Type>, ty: &'a Type) {
            all.insert(ty);
            match ty {
                Type::Ident(_) | Type::Str(_) | Type::Void(_) | Type::SliceRefU8(_) => {}
                Type::RustBox(ty)
                | Type::UniquePtr(ty)
                | Type::CxxVector(ty)
                | Type::RustVec(ty) => visit(all, &ty.inner),
                Type::Ref(r) => visit(all, &r.inner),
                Type::Slice(s) => visit(all, &s.inner),
                Type::Fn(f) => {
                    if let Some(ret) = &f.ret {
                        visit(all, ret);
                    }
                    for arg in &f.args {
                        visit(all, &arg.ty);
                    }
                }
            }
        }

        let mut type_names = UnorderedSet::new();
        let mut function_names = UnorderedSet::new();
        for api in apis {
            match api {
                Api::Include(_) => {}
                Api::Struct(strct) => {
                    let ident = &strct.ident;
                    if type_names.insert(ident) {
                        structs.insert(ident, strct);
                    } else {
                        duplicate_name(cx, strct, ident);
                    }
                    for field in &strct.fields {
                        visit(&mut all, &field.ty);
                    }
                }
                Api::Enum(enm) => {
                    let ident = &enm.ident;
                    // We allow declaring the same type as a shared enum and as a Cxxtype, as this
                    // means not to emit the C++ enum definition.
                    if !type_names.insert(ident) && !cxx.contains(ident) {
                        duplicate_name(cx, enm, ident);
                    }
                    enums.insert(ident, enm);
                }
                Api::CxxType(ety) => {
                    let ident = &ety.ident;
                    // We allow declaring the same type as a shared enum and as a Cxxtype, as this
                    // means not to emit the C++ enum definition.
                    if !type_names.insert(ident) && !enums.contains_key(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    cxx.insert(ident);
                }
                Api::RustType(ety) => {
                    let ident = &ety.ident;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    rust.insert(ident);
                }
                Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                    let ident = &efn.ident;
                    if !function_names.insert((&efn.receiver, ident)) {
                        duplicate_name(cx, efn, ident);
                    }
                    for arg in &efn.args {
                        visit(&mut all, &arg.ty);
                    }
                    if let Some(ret) = &efn.ret {
                        visit(&mut all, ret);
                    }
                }
                Api::TypeAlias(alias) => {
                    let ident = &alias.ident;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, alias, ident);
                    }
                    cxx.insert(ident);
                    aliases.insert(ident, alias);
                }
            }
        }

        Types {
            all,
            structs,
            enums,
            cxx,
            rust,
            aliases,
        }
    }

    pub fn needs_indirect_abi(&self, ty: &Type) -> bool {
        match ty {
            Type::Ident(ident) => {
                if let Some(strct) = self.structs.get(ident) {
                    !self.is_pod(strct)
                } else {
                    Atom::from(ident) == Some(RustString)
                }
            }
            Type::RustVec(_) => true,
            _ => false,
        }
    }

    pub fn is_pod(&self, strct: &Struct) -> bool {
        for derive in &strct.derives {
            if *derive == Derive::Copy {
                return true;
            }
        }
        false
    }
}

impl<'t, 'a> IntoIterator for &'t Types<'a> {
    type Item = &'a Type;
    type IntoIter = crate::syntax::set::Iter<'t, 'a, Type>;
    fn into_iter(self) -> Self::IntoIter {
        self.all.into_iter()
    }
}

fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
    let msg = format!("the name `{}` is defined multiple times", ident);
    cx.error(sp, msg);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

#[derive(Debug, Eq, PartialEq)]
struct Env(Vec<Def>);

impl IntoIterator for Env {
    type Item = Def;
    type IntoIter = ::std::vec::IntoIter<Def>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl Env {
  fn new() -> Env {
    Env(Vec::new())
  }

  fn get_val(self, var: &Var) -> Option<Def> {
    self.into_iter().rev().find(|&ref def| {
      match *def {
        Def::Val(ref v, _) => *v == *var,
        Def::Ty(_, _) => false,
      }
    })
  }

  fn push(&mut self, def: Def) {
    self.0.push(def)
  }
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    if line == ":env" {
      println!("{:?}", env);
    } else if line == ":history" {
      println!("{:?}", history);
    } else if line == ":quit" {
      break;
    } else if line.len() > 0 {
      history.push(line.clone());
      match parse_one(&line[..]) {
        Ok(one) => {
          match one {
            One::Def(ref def) => {
              print!("{:?}", one);
              env.push(def.clone());
            }
            One::Expr(_) => print!("{:?}", one.normalize()),
          }
        }
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  // Return 0 if repl returned Ok.
  std::process::exit(!repl().is_ok() as i32)
}
<commit_msg>Implement Debug for Env. Begin implementing environment aware normalizing.<commit_after>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::fmt::{Debug, Formatter};
use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

#[derive(Eq, PartialEq)]
struct Env(Vec<Def>);

impl Debug for Env {
  fn fmt(&self, fmt: &mut Formatter) -> std::fmt::Result {
    for def in &self.0 {
      try!(writeln!(fmt, "{:?}", def));
    }
    Ok(())
  }
}

// impl IntoIterator for Env {
//     type Item = Def;
//     type IntoIter = ::std::vec::IntoIter<Def>;

//     fn into_iter(self) -> Self::IntoIter {
//         self.0.into_iter()
//     }
// }

impl Env {
  fn new() -> Env {
    Env(Vec::new())
  }

  fn get_val(&self, var: &Var) -> Option<&Def> {
    self.0.iter().rev().find(|def| {
      match **def {
        Def::Val(ref v, _) => *v == *var,
        Def::Ty(_, _) => false,
      }
    })
  }

  fn push(&mut self, def: Def) {
    self.0.push(def)
  }

  fn pop(&mut self) {
    self.0.pop();
  }
}

fn normalize_in(e: &Expr, env: &mut Env) -> Expr {
  match *e {
    Expr::Const(ref constant) => Expr::Const(constant.clone()),
    Expr::Var(ref var) => {
      match env.get_val(var) {
        Some(ref def) => def.expr().clone(),
        None => Expr::Var(var.clone()),
      }
    }
    Expr::Lam(ref var, ref ty, ref body) => {
      env.push(Def::Val(var.clone(), Expr::Var(var.clone())));
      let ty = normalize_in(ty, env);
      let body = normalize_in(body, env);
      let lam = Expr::Lam(var.clone(), Box::new(ty), Box::new(body));
      env.pop();
      lam
    }
    Expr::Pi(ref var, ref ty, ref body) => {
      env.push(Def::Ty(var.clone(), Expr::Var(var.clone())));
      let ty = normalize_in(ty, env);
      let body = normalize_in(body, env);
      let pi = Expr::Pi(var.clone(), Box::new(ty), Box::new(body));
      env.pop();
      pi
    }
    Expr::App(ref f, ref arg) => {
      let f = f.normalize();
      // let f = *f.clone();
      let arg = arg.normalize();
      Expr::App(Box::new(f), Box::new(arg))
      // if let Expr::Lam(var, _, body) = f {
      // let lam = replace(&var, &arg, &body).normalize();
      // println!("normalized = {}", lam.to_string());
      // lam
      // } else if let Expr::Pi(var, _, body) = f {
      // let pi = replace(&var, &arg, &body).normalize();
      // println!("normalized = {}", pi.to_string());
      // pi
      // } else {
      // panic!("f isn't a function {}", f.to_string())
      // Expr::App(Box::new(f), Box::new(arg))
      // }
    }
  }
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    if line == ":env" {
      print!("{:?}", env);
    } else if line == ":history" {
      println!("{:?}", history);
    } else if line == ":quit" {
      break;
    } else if line.len() > 0 {
      history.push(line.clone());
      match parse_one(&line[..]) {
        Ok(one) => {
          match one {
            One::Def(ref def) => {
              print!("{:?}", one);
              env.push(def.clone());
            }
            One::Expr(ref e) => {
              print!("{:?}", One::Expr(normalize_in(e, &mut env)))
            }
          }
        }
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  // Return 0 if repl returned Ok.
  std::process::exit(!repl().is_ok() as i32)
}
<|endoftext|>


<commit_before>use serialize::json::{Json, ToJson};

bitflags! {
    #[deriving(Show)] flags WSHeader: u16 {
        // Main structure, mask with & to get header parts
        static WS_FIN     = 0b1000000000000000, // final flag
        static WS_RSV     = 0b0111000000000000, // reserved
        static WS_OPCODE  = 0b0000111100000000, // opcode
        static WS_MASK    = 0b0000000010000000, // mask flag
        static WS_LEN     = 0b0000000001111111, // length

        // Opcodes, check for equality after masking with WS_OPCODE
        static WS_OPCONT  = 0b0000000000000000,
        static WS_OPTEXT  = 0b0000000100000000,
        static WS_OPBIN   = 0b0000001000000000,
        static WS_OPTERM  = 0b0000100000000000,
        static WS_OPPING  = 0b0000100100000000,
        static WS_OPPONG  = 0b0000101000000000,

        // Helper masks
        static WS_OPCTRL  = 0b0000100000000000, // if matches with &, this is a control code
        static WS_LEN16   = 0b0000000001111110, // if &WS_LEN equals this, it has 16-bit length
        static WS_LEN64   = 0b0000000001111111, // if &WS_LEN equals this, it has 32-bit length
    }
}

#[deriving(Show)]
pub struct WSMessage {
    pub header: WSHeader,
    pub data: Vec<u8>
}

impl WSMessage {
    pub fn to_string(&self) -> String {
        String::from_utf8_lossy(self.data.as_slice()).into_string()
    }
}

impl ToJson for WSMessage {
    fn to_json(&self) -> Json {
        from_str::<Json>(self.to_string().as_slice()).unwrap()
    }
}

<commit_msg>bitflags! macro update: static -> const<commit_after>use serialize::json::{Json, ToJson};

bitflags! {
    #[deriving(Show)] flags WSHeader: u16 {
        // Main structure, mask with & to get header parts
        const WS_FIN     = 0b1000000000000000, // final flag
        const WS_RSV     = 0b0111000000000000, // reserved
        const WS_OPCODE  = 0b0000111100000000, // opcode
        const WS_MASK    = 0b0000000010000000, // mask flag
        const WS_LEN     = 0b0000000001111111, // length

        // Opcodes, check for equality after masking with WS_OPCODE
        const WS_OPCONT  = 0b0000000000000000,
        const WS_OPTEXT  = 0b0000000100000000,
        const WS_OPBIN   = 0b0000001000000000,
        const WS_OPTERM  = 0b0000100000000000,
        const WS_OPPING  = 0b0000100100000000,
        const WS_OPPONG  = 0b0000101000000000,

        // Helper masks
        const WS_OPCTRL  = 0b0000100000000000, // if matches with &, this is a control code
        const WS_LEN16   = 0b0000000001111110, // if &WS_LEN equals this, it has 16-bit length
        const WS_LEN64   = 0b0000000001111111, // if &WS_LEN equals this, it has 32-bit length
    }
}

#[deriving(Show)]
pub struct WSMessage {
    pub header: WSHeader,
    pub data: Vec<u8>
}

impl WSMessage {
    pub fn to_string(&self) -> String {
        String::from_utf8_lossy(self.data.as_slice()).into_string()
    }
}

impl ToJson for WSMessage {
    fn to_json(&self) -> Json {
        from_str::<Json>(self.to_string().as_slice()).unwrap()
    }
}

<|endoftext|>


<commit_before>use std::ops::{Deref, DerefMut};
use std::sync::mpsc::{channel, Sender, Receiver};

use types::{AudioDevice, MessageReceiver, Sample, Time};

/// Bundles a `MessageReceiver` with threaded message passing.
///
/// # Sending messages
///
/// Once a device is wrapped with `Messaged`, one or more `Sender`s can be
/// returned from it. These represent the send end of standard Rust channels,
/// and can be sent between threads freely.
///
/// # As an `AudioDevice`
///
/// The wrapper implements `AudioDevice` if the contained device does as well.
/// The implementation first checks for any incoming messages, then applies them
/// to the interior device. Once the messages have been handled, it calls the
/// normal `tick` function of the device.
///
/// This allows one to wrap a device in `Messaged`, move the sender to another
/// thread, then drop the `Messaged` device into a normal container, such as
/// `DeviceChain` or `DeviceGraph`. It will automatically receive and handle its
/// own messages while processing.
///
/// # Example
///
/// ```
/// use std::thread;
/// use oxcable::chain::{DeviceChain, Tick};
/// use oxcable::oscillator::{Oscillator, Sine, SetFreq};
/// use oxcable::io::audio::AudioEngine;
/// use oxcable::wrappers::Messaged;
///
/// fn main() {
/// # // this example uses tick_forever(), so we wrap it in a function that gets
/// # // compiled by not run by doctest
/// # }
/// # fn dummy() {
///     // Initialize signal chain...
///     let tx;
///     let engine = AudioEngine::with_buffer_size(256).unwrap();
///     let mut chain = DeviceChain::from({
///         let msgd = Messaged::from(Oscillator::new(Sine).freq(440.0));
///         tx = msgd.get_sender();
///         msgd
///     }).into(
///         engine.default_output(1).unwrap()
///     );
///
///     // Send the messager to a new thread. It will wait for one second, then
///     // set the oscillator to a higher frequency.
///     thread::spawn(move || {
///         thread::sleep_ms(1000);
///         tx.send(SetFreq(880.0));
///     });
///
///     // Generate two seconds of audio, then exit...
///     chain.tick_n_times(88200);
/// }
/// ```
pub struct Messaged<D> where D: MessageReceiver {
    /// The device being wrapped.
    pub device: D,
    tx: Sender<D::Msg>,
    rx: Receiver<D::Msg>,
}

impl<D> Messaged<D> where D: MessageReceiver {
    /// Return the sending half of our communication channel.
    pub fn get_sender(&self) -> Sender<D::Msg> {
        self.tx.clone()
    }
}

impl<D> From<D> for Messaged<D> where D: MessageReceiver {
    fn from(device: D) -> Self {
        let (tx, rx) = channel();
        Messaged {
            device: device,
            tx: tx,
            rx: rx,
        }
    }
}

impl<D> AudioDevice for Messaged<D> where D: AudioDevice+MessageReceiver {
    fn num_inputs(&self) -> usize {
        self.device.num_inputs()
    }

    fn num_outputs(&self) -> usize {
        self.device.num_outputs()
    }

    fn tick(&mut self, t: Time, inputs: &[Sample], outputs: &mut[Sample]) {
        loop {
            match self.rx.try_recv() {
                Ok(msg) => self.device.handle_message(msg),
                _ => break
            }
        }
        self.device.tick(t, inputs, outputs);
    }
}

impl<D> Deref for Messaged<D> where D: MessageReceiver {
    type Target = D;
    fn deref(&self) -> &D {
        &self.device
    }
}

impl<D> DerefMut for Messaged<D> where D: MessageReceiver {
    fn deref_mut(&mut self) -> &mut D {
        &mut self.device
    }
}
<commit_msg>Make Messaged deref to an AudioDevice<commit_after>use std::ops::{Deref, DerefMut};
use std::sync::mpsc::{channel, Sender, Receiver};

use types::{AudioDevice, MessageReceiver, Sample, Time};

/// Bundles a `MessageReceiver` with threaded message passing.
///
/// # Sending messages
///
/// Once a device is wrapped with `Messaged`, one or more `Sender`s can be
/// returned from it. These represent the send end of standard Rust channels,
/// and can be sent between threads freely.
///
/// # As an `AudioDevice`
///
/// The wrapper implements `AudioDevice` if the contained device does as well.
/// The implementation first checks for any incoming messages, then applies them
/// to the interior device. Once the messages have been handled, it calls the
/// normal `tick` function of the device.
///
/// This allows one to wrap a device in `Messaged`, move the sender to another
/// thread, then drop the `Messaged` device into a normal container, such as
/// `DeviceChain` or `DeviceGraph`. It will automatically receive and handle its
/// own messages while processing.
///
/// # Example
///
/// ```
/// use std::thread;
/// use oxcable::chain::{DeviceChain, Tick};
/// use oxcable::oscillator::{Oscillator, Sine, SetFreq};
/// use oxcable::io::audio::AudioEngine;
/// use oxcable::wrappers::Messaged;
///
/// fn main() {
/// # // this example uses tick_forever(), so we wrap it in a function that gets
/// # // compiled by not run by doctest
/// # }
/// # fn dummy() {
///     // Initialize signal chain...
///     let tx;
///     let engine = AudioEngine::with_buffer_size(256).unwrap();
///     let mut chain = DeviceChain::from({
///         let msgd = Messaged::from(Oscillator::new(Sine).freq(440.0));
///         tx = msgd.get_sender();
///         msgd
///     }).into(
///         engine.default_output(1).unwrap()
///     );
///
///     // Send the messager to a new thread. It will wait for one second, then
///     // set the oscillator to a higher frequency.
///     thread::spawn(move || {
///         thread::sleep_ms(1000);
///         tx.send(SetFreq(880.0));
///     });
///
///     // Generate two seconds of audio, then exit...
///     chain.tick_n_times(88200);
/// }
/// ```
pub struct Messaged<D> where D: MessageReceiver {
    /// The device being wrapped.
    pub device: D,
    tx: Sender<D::Msg>,
    rx: Receiver<D::Msg>,
}

impl<D> Messaged<D> where D: MessageReceiver {
    /// Return the sending half of our communication channel.
    pub fn get_sender(&self) -> Sender<D::Msg> {
        self.tx.clone()
    }
}

impl<D> From<D> for Messaged<D> where D: MessageReceiver {
    fn from(device: D) -> Self {
        let (tx, rx) = channel();
        Messaged {
            device: device,
            tx: tx,
            rx: rx,
        }
    }
}

impl<D> AudioDevice for Messaged<D> where D: AudioDevice+MessageReceiver {
    fn num_inputs(&self) -> usize {
        self.device.num_inputs()
    }

    fn num_outputs(&self) -> usize {
        self.device.num_outputs()
    }

    fn tick(&mut self, t: Time, inputs: &[Sample], outputs: &mut[Sample]) {
        loop {
            match self.rx.try_recv() {
                Ok(msg) => self.device.handle_message(msg),
                _ => break
            }
        }
        self.device.tick(t, inputs, outputs);
    }
}

impl<D> Deref for Messaged<D> where D: AudioDevice+MessageReceiver {
    type Target = D;
    fn deref(&self) -> &D {
        &self.device
    }
}

impl<D> DerefMut for Messaged<D> where D: AudioDevice+MessageReceiver {
    fn deref_mut(&mut self) -> &mut D {
        &mut self.device
    }
}
<|endoftext|>


<commit_before>//! Trait for generic events

use std::any::Any;

use {AfterRenderEvent, ButtonEvent, ControllerAxisEvent, CursorEvent, FocusEvent, IdleEvent, MouseCursorEvent,
     MouseRelativeEvent, MouseScrollEvent, PressEvent, ReleaseEvent, RenderEvent, ResizeEvent,
     TextEvent, TouchEvent, UpdateEvent};
use {Event, EventId, Input, Loop, Motion};
use {AFTER_RENDER, BUTTON, CONTROLLER_AXIS, CURSOR, FOCUS, CLOSE, IDLE, MOUSE_CURSOR, MOUSE_RELATIVE,
     MOUSE_SCROLL, RENDER, RESIZE, TEXT, TOUCH, UPDATE};

/// Implemented by all events
pub trait GenericEvent: Sized +
    AfterRenderEvent + ControllerAxisEvent + CursorEvent + FocusEvent + IdleEvent +
    MouseCursorEvent + MouseRelativeEvent + MouseScrollEvent +
    ButtonEvent + PressEvent + ReleaseEvent + RenderEvent + ResizeEvent +
    TextEvent + TouchEvent + UpdateEvent +
    From<Input> + From<Loop> + Into<Option<Input>> + Into<Option<Loop>>
{
/// The id of this event.
    fn event_id(&self) -> EventId;
/// Calls closure with arguments
    fn with_args<'a, F, U>(&'a self, f: F) -> U
        where F: FnMut(&Any) -> U
;
}

impl GenericEvent for Event {
    fn event_id(&self) -> EventId {
        match *self {
            Event::Input(Input::Cursor(_)) => CURSOR,
            Event::Input(Input::Focus(_)) => FOCUS,
            Event::Input(Input::Close(_)) => CLOSE,
            Event::Input(Input::Move(Motion::MouseCursor(_, _))) => MOUSE_CURSOR,
            Event::Input(Input::Move(Motion::MouseRelative(_, _))) => MOUSE_RELATIVE,
            Event::Input(Input::Move(Motion::MouseScroll(_, _))) => MOUSE_SCROLL,
            Event::Input(Input::Move(Motion::ControllerAxis(_))) => CONTROLLER_AXIS,
            Event::Input(Input::Move(Motion::Touch(_))) => TOUCH,
            Event::Input(Input::Button(_)) => BUTTON,
            Event::Input(Input::Resize(_, _)) => RESIZE,
            Event::Input(Input::Text(_)) => TEXT,
            Event::Loop(Loop::Update(_)) => UPDATE,
            Event::Loop(Loop::Render(_)) => RENDER,
            Event::Loop(Loop::AfterRender(_)) => AFTER_RENDER,
            Event::Loop(Loop::Idle(_)) => IDLE,
            Event::Custom(event_id, _) => event_id,
        }
    }

    fn with_args<'a, F, U>(&'a self, mut f: F) -> U
        where F: FnMut(&Any) -> U
    {
        match *self {
            Event::Input(Input::Cursor(cursor)) => f(&cursor as &Any),
            Event::Input(Input::Focus(focused)) => f(&focused as &Any),
            Event::Input(Input::Close(ref args)) => f(args as &Any),
            Event::Input(Input::Move(Motion::ControllerAxis(args))) => f(&args as &Any),
            Event::Input(Input::Move(Motion::MouseCursor(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::MouseRelative(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::MouseScroll(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::Touch(args))) => f(&args as &Any),
            Event::Input(Input::Button(ref args)) => f(args as &Any),
            Event::Input(Input::Resize(w, h)) => f(&(w, h) as &Any),
            Event::Input(Input::Text(ref text)) => f(text as &Any),
            Event::Loop(Loop::Update(ref args)) => f(args as &Any),
            Event::Loop(Loop::Render(ref args)) => f(args as &Any),
            Event::Loop(Loop::AfterRender(ref args)) => f(args as &Any),
            Event::Loop(Loop::Idle(ref args)) => f(args as &Any),
            Event::Custom(_, ref args) => f(args),
        }
    }
}
<commit_msg>Add CloseEvent bound to GenericEvent<commit_after>//! Trait for generic events

use std::any::Any;

use {AfterRenderEvent, ButtonEvent, CloseEvent, ControllerAxisEvent, CursorEvent, FocusEvent,
     IdleEvent, MouseCursorEvent, MouseRelativeEvent, MouseScrollEvent, PressEvent, ReleaseEvent,
     RenderEvent, ResizeEvent, TextEvent, TouchEvent, UpdateEvent};
use {Event, EventId, Input, Loop, Motion};
use {AFTER_RENDER, BUTTON, CONTROLLER_AXIS, CURSOR, FOCUS, CLOSE, IDLE, MOUSE_CURSOR, MOUSE_RELATIVE,
     MOUSE_SCROLL, RENDER, RESIZE, TEXT, TOUCH, UPDATE};

/// Implemented by all events
pub trait GenericEvent: Sized +
    AfterRenderEvent + CloseEvent + ControllerAxisEvent + CursorEvent + FocusEvent + IdleEvent +
    MouseCursorEvent + MouseRelativeEvent + MouseScrollEvent + ButtonEvent + PressEvent +
    ReleaseEvent + RenderEvent + ResizeEvent + TextEvent + TouchEvent + UpdateEvent +
    From<Input> + From<Loop> + Into<Option<Input>> + Into<Option<Loop>>
{
/// The id of this event.
    fn event_id(&self) -> EventId;
/// Calls closure with arguments
    fn with_args<'a, F, U>(&'a self, f: F) -> U
        where F: FnMut(&Any) -> U
;
}

impl GenericEvent for Event {
    fn event_id(&self) -> EventId {
        match *self {
            Event::Input(Input::Cursor(_)) => CURSOR,
            Event::Input(Input::Focus(_)) => FOCUS,
            Event::Input(Input::Close(_)) => CLOSE,
            Event::Input(Input::Move(Motion::MouseCursor(_, _))) => MOUSE_CURSOR,
            Event::Input(Input::Move(Motion::MouseRelative(_, _))) => MOUSE_RELATIVE,
            Event::Input(Input::Move(Motion::MouseScroll(_, _))) => MOUSE_SCROLL,
            Event::Input(Input::Move(Motion::ControllerAxis(_))) => CONTROLLER_AXIS,
            Event::Input(Input::Move(Motion::Touch(_))) => TOUCH,
            Event::Input(Input::Button(_)) => BUTTON,
            Event::Input(Input::Resize(_, _)) => RESIZE,
            Event::Input(Input::Text(_)) => TEXT,
            Event::Loop(Loop::Update(_)) => UPDATE,
            Event::Loop(Loop::Render(_)) => RENDER,
            Event::Loop(Loop::AfterRender(_)) => AFTER_RENDER,
            Event::Loop(Loop::Idle(_)) => IDLE,
            Event::Custom(event_id, _) => event_id,
        }
    }

    fn with_args<'a, F, U>(&'a self, mut f: F) -> U
        where F: FnMut(&Any) -> U
    {
        match *self {
            Event::Input(Input::Cursor(cursor)) => f(&cursor as &Any),
            Event::Input(Input::Focus(focused)) => f(&focused as &Any),
            Event::Input(Input::Close(ref args)) => f(args as &Any),
            Event::Input(Input::Move(Motion::ControllerAxis(args))) => f(&args as &Any),
            Event::Input(Input::Move(Motion::MouseCursor(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::MouseRelative(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::MouseScroll(x, y))) => f(&(x, y) as &Any),
            Event::Input(Input::Move(Motion::Touch(args))) => f(&args as &Any),
            Event::Input(Input::Button(ref args)) => f(args as &Any),
            Event::Input(Input::Resize(w, h)) => f(&(w, h) as &Any),
            Event::Input(Input::Text(ref text)) => f(text as &Any),
            Event::Loop(Loop::Update(ref args)) => f(args as &Any),
            Event::Loop(Loop::Render(ref args)) => f(args as &Any),
            Event::Loop(Loop::AfterRender(ref args)) => f(args as &Any),
            Event::Loop(Loop::Idle(ref args)) => f(args as &Any),
            Event::Custom(_, ref args) => f(args),
        }
    }
}
<|endoftext|>


<commit_before>//
// Tests for the pwx binary
//

use std::process::Command;
use std::path::PathBuf;
use std::env::current_exe;

macro_rules! pwxrun {
    ($($arg:expr),*) => {{
        let binpath = current_exe().unwrap()
                        .parent().expect("executable path")
                        .to_path_buf().join("pwx");
        Command::new(&binpath)
            .env("PWX_PASSWORD", "test")
            .env("PWX_DATABASE", "tests/test.psafe3")
            $(.arg($arg))*
            .output().unwrap_or_else(|e| {panic!("Failed to execute pwx({}) {}", binpath.to_string_lossy(), e)})
    }};
}

/* Show all entries in the DB */
#[test]
fn list() {
    let output = pwxrun!("list");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 3);
}

/* Filter by title */
#[test]
fn list_title() {
    let output = pwxrun!("list", "-T", "face");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Filter by User */
#[test]
fn list_user() {
    let output = pwxrun!("list", "-U", "testuser");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Filter by Group */
#[test]
fn list_group() {
    let output = pwxrun!("list", "-G", "social");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
    assert!(sout.contains("facebook"));
}

/* Filter by URL */
#[test]
fn list_url() {
    let output = pwxrun!("list", "-R", "facebook.com");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* list <filter> searches all text fields */
#[test]
fn list_filter() {
    let output = pwxrun!("list", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 2);

    // Filters
    let output = pwxrun!("list", "-U", "some", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);

    // Narrow a query with multiple filters
    let output = pwxrun!("list", "some", "facebook");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);

    let output = pwxrun!("list", "some", "facebook", "none");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Same as the filter tests, but for count */
#[test]
fn count() {
    let output = pwxrun!("count", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("2"));

    // Filters
    let output = pwxrun!("count", "-U", "some", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("1"));

    // Narrow a query with multiple filters
    let output = pwxrun!("count", "some", "facebook");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("1"));

    let output = pwxrun!("count", "some", "facebook", "none");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("0"));
}

#[test]
fn get() {
    // URL
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "url");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "https://facebook.com");

    // Group
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "group");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "social");

    // Group
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "notes");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "Some notes");

    // Command is not set so the command fails
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "command");
    assert!(!output.status.success());

    // password
    let output = pwxrun!("get", "63a19136-46d9-4f75-827b-5312574233e8", "password");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "testpassverylong");
}

<commit_msg>Cleanup: Removed unused import<commit_after>//
// Tests for the pwx binary
//

use std::process::Command;
use std::env::current_exe;

macro_rules! pwxrun {
    ($($arg:expr),*) => {{
        let binpath = current_exe().unwrap()
                        .parent().expect("executable path")
                        .to_path_buf().join("pwx");
        Command::new(&binpath)
            .env("PWX_PASSWORD", "test")
            .env("PWX_DATABASE", "tests/test.psafe3")
            $(.arg($arg))*
            .output().unwrap_or_else(|e| {panic!("Failed to execute pwx({}) {}", binpath.to_string_lossy(), e)})
    }};
}

/* Show all entries in the DB */
#[test]
fn list() {
    let output = pwxrun!("list");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 3);
}

/* Filter by title */
#[test]
fn list_title() {
    let output = pwxrun!("list", "-T", "face");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Filter by User */
#[test]
fn list_user() {
    let output = pwxrun!("list", "-U", "testuser");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Filter by Group */
#[test]
fn list_group() {
    let output = pwxrun!("list", "-G", "social");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
    assert!(sout.contains("facebook"));
}

/* Filter by URL */
#[test]
fn list_url() {
    let output = pwxrun!("list", "-R", "facebook.com");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* list <filter> searches all text fields */
#[test]
fn list_filter() {
    let output = pwxrun!("list", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 2);

    // Filters
    let output = pwxrun!("list", "-U", "some", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);

    // Narrow a query with multiple filters
    let output = pwxrun!("list", "some", "facebook");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);

    let output = pwxrun!("list", "some", "facebook", "none");
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim().split('\n').count(), 1);
}

/* Same as the filter tests, but for count */
#[test]
fn count() {
    let output = pwxrun!("count", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("2"));

    // Filters
    let output = pwxrun!("count", "-U", "some", "some");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("1"));

    // Narrow a query with multiple filters
    let output = pwxrun!("count", "some", "facebook");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("1"));

    let output = pwxrun!("count", "some", "facebook", "none");
    let sout = String::from_utf8_lossy(&output.stdout);
    assert_eq!(sout.trim().split('\n').nth(0), Some("0"));
}

#[test]
fn get() {
    // URL
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "url");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "https://facebook.com");

    // Group
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "group");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "social");

    // Group
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "notes");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "Some notes");

    // Command is not set so the command fails
    let output = pwxrun!("get", "43fe1d0e-b65f-4e48-9abf-a1c5a1beeee8", "command");
    assert!(!output.status.success());

    // password
    let output = pwxrun!("get", "63a19136-46d9-4f75-827b-5312574233e8", "password");
    assert!(output.status.success());
    let sout = String::from_utf8_lossy(&output.stdout);
    println!("{}", sout);
    assert_eq!(sout.trim(), "testpassverylong");
}

<|endoftext|>


<commit_before>extern crate assert_cmd;
extern crate predicates;
extern crate tempdir;
extern crate fs_extra;

use fs_extra::dir::copy;
use fs_extra::dir::CopyOptions;
use fs_extra::file::move_file;
use std::path::PathBuf;
use std::fs;
use assert_cmd::prelude::*;
use std::process::Command;
use tempdir::TempDir;

fn get_test_folder() -> PathBuf {
    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("tests");
    return d;
}

fn get_resource_folder() -> PathBuf {
    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("tests");
    d.push("resources");
    return d;
}

fn setup_test_folder() -> TempDir {
    let mut res = get_resource_folder();
    res.push("base");
    let parent = get_test_folder();
    let tmp_dir = TempDir::new_in(parent, "test").unwrap();

    {
        let tmp_path = tmp_dir.path();

        let options = CopyOptions::new(); //Initialize default values for CopyOptions
        copy(&res, tmp_path, &options).unwrap();
    }

    return tmp_dir;
}

#[test]
fn temporary_bw_files_are_removed() {
    let aux = setup_test_folder();
    let mut src_path = aux.path().to_path_buf();
    src_path.push("base");

    println!("Test files in {:?}", src_path);

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&src_path)
       .arg("ref2.fa")
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .assert().success();

    // assert some files exist
    // reads.bw
    let mut bw_out = src_path.clone();
    bw_out.push("reads.bw");
    assert!(bw_out.exists());

    // assert some files are removed
    // chromInfo*.tmp
    // wiggle*.tmp
    for entry in fs::read_dir(&src_path).unwrap() {
        let entry = entry.unwrap();
        let filename = entry.file_name().into_string().unwrap();

        if ( filename.starts_with("chromInfo") || filename.starts_with("wiggle") ) && filename.ends_with(".tmp") {
            panic!("Temporary file has not been removed: {}", filename);
        }
    }
}

#[test]
fn supplied_tallymer_path_is_respected() {
    let aux = setup_test_folder();
    let mut src_path = aux.path().to_path_buf();
    src_path.push("base");

    // get tallymer path
    let mut tallymer_path = get_resource_folder();
    tallymer_path.push("tallymer");
    tallymer_path.push("ref2.tal_5.gtTxt.gz");

    println!("Test files in {:?}", src_path);

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&src_path)
       .arg("ref2.fa")
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .arg(format!("--tallymer={}", tallymer_path.to_str().unwrap()))
       .assert().success();

    // check that tallymer file was not created
    let mut tally_bad = src_path.clone();
    tally_bad.push("ref2.tal_5.gtTxt.gz");
    assert!(!tally_bad.exists());

    // assert some files exist
    // reads.bw
    let mut bw_out = src_path.clone();
    bw_out.push("reads.bw");
    assert!(bw_out.exists());
}

fn file_exists_in_folder(filename: &str, path: &PathBuf) -> bool {
    let mut file_path = path.clone();
    file_path.push(filename);
    return file_path.exists();
}

#[test]
fn user_specified_genome_tools_working_directory() {
    // setup two folders
    // 1. folder containing refseq dataset and where genome tools will operate
    let mut res = get_resource_folder();
    res.push("base");
    let parent = get_test_folder();
    let gt_folder = TempDir::new_in(&parent, "test_gt").unwrap();

    {
        let tmp_path = gt_folder.path();

        let options = CopyOptions::new(); //Initialize default values for CopyOptions
        copy(&res, tmp_path, &options).unwrap();
    }
    let mut gt_path = gt_folder.path().to_path_buf();
    gt_path.push("base");

    // 2. folder where main program will operate
    let main_folder = TempDir::new_in(&parent, "test_main").unwrap();
    let main_path = main_folder.path().to_path_buf();
    let move_options = fs_extra::file::CopyOptions::new();
    let mut bam_src = gt_path.clone();
    bam_src.push("reads.bam");
    let mut bam_tgt = main_path.clone();
    bam_tgt.push("reads.bam");
    move_file(bam_src, bam_tgt, &move_options).unwrap();

    // execute command
    let mut ref_path = gt_path.clone();
    ref_path.push("ref2.fa");

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&main_path)
       .arg(ref_path)
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .arg(format!("--gt-workdir={}", gt_path.to_str().unwrap()))
       .assert().success();

    // check that output files exist in the main directory
    assert!(file_exists_in_folder("reads.bw", &main_path));
    assert!(file_exists_in_folder("ref2.tal_5.gtTxt.gz", &main_path));

    // check that genome tools temporary files do not exist in the main directory
    assert!(!file_exists_in_folder("ref2.fa.sa", &main_path));
    assert!(!file_exists_in_folder("ref2.sft.suf", &main_path));
}
<commit_msg>Fix tests<commit_after>extern crate assert_cmd;
extern crate predicates;
extern crate tempdir;
extern crate fs_extra;

use fs_extra::dir::copy;
use fs_extra::dir::CopyOptions;
use fs_extra::file::move_file;
use std::path::PathBuf;
use std::fs;
use assert_cmd::prelude::*;
use std::process::Command;
use tempdir::TempDir;

fn get_test_folder() -> PathBuf {
    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("tests");
    return d;
}

fn get_resource_folder() -> PathBuf {
    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.push("tests");
    d.push("resources");
    return d;
}

fn setup_test_folder() -> TempDir {
    let mut res = get_resource_folder();
    res.push("base");
    let parent = get_test_folder();
    let tmp_dir = TempDir::new_in(parent, "test").unwrap();

    {
        let tmp_path = tmp_dir.path();

        let options = CopyOptions::new(); //Initialize default values for CopyOptions
        copy(&res, tmp_path, &options).unwrap();
    }

    return tmp_dir;
}

#[test]
fn temporary_bw_files_are_removed() {
    let aux = setup_test_folder();
    let mut src_path = aux.path().to_path_buf();
    src_path.push("base");

    println!("Test files in {:?}", src_path);

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&src_path)
       .arg("ref2.fa")
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .assert().success();

    // assert some files exist
    // reads.bw
    let mut bw_out = src_path.clone();
    bw_out.push("reads.bigWig");
    assert!(bw_out.exists());

    // assert some files are removed
    // chromInfo*.tmp
    // wiggle*.tmp
    for entry in fs::read_dir(&src_path).unwrap() {
        let entry = entry.unwrap();
        let filename = entry.file_name().into_string().unwrap();

        if ( filename.starts_with("chromInfo") || filename.starts_with("wiggle") ) && filename.ends_with(".tmp") {
            panic!("Temporary file has not been removed: {}", filename);
        }
    }
}

#[test]
fn supplied_tallymer_path_is_respected() {
    let aux = setup_test_folder();
    let mut src_path = aux.path().to_path_buf();
    src_path.push("base");

    // get tallymer path
    let mut tallymer_path = get_resource_folder();
    tallymer_path.push("tallymer");
    tallymer_path.push("ref2.tal_5.gtTxt.gz");

    println!("Test files in {:?}", src_path);

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&src_path)
       .arg("ref2.fa")
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .arg(format!("--tallymer={}", tallymer_path.to_str().unwrap()))
       .assert().success();

    // check that tallymer file was not created
    let mut tally_bad = src_path.clone();
    tally_bad.push("ref2.tal_5.gtTxt.gz");
    assert!(!tally_bad.exists());

    // assert some files exist
    // reads.bw
    let mut bw_out = src_path.clone();
    bw_out.push("reads.bigWig");
    assert!(bw_out.exists());
}

fn file_exists_in_folder(filename: &str, path: &PathBuf) -> bool {
    let mut file_path = path.clone();
    file_path.push(filename);
    return file_path.exists();
}

#[test]
fn user_specified_genome_tools_working_directory() {
    // setup two folders
    // 1. folder containing refseq dataset and where genome tools will operate
    let mut res = get_resource_folder();
    res.push("base");
    let parent = get_test_folder();
    let gt_folder = TempDir::new_in(&parent, "test_gt").unwrap();

    {
        let tmp_path = gt_folder.path();

        let options = CopyOptions::new(); //Initialize default values for CopyOptions
        copy(&res, tmp_path, &options).unwrap();
    }
    let mut gt_path = gt_folder.path().to_path_buf();
    gt_path.push("base");

    // 2. folder where main program will operate
    let main_folder = TempDir::new_in(&parent, "test_main").unwrap();
    let main_path = main_folder.path().to_path_buf();
    let move_options = fs_extra::file::CopyOptions::new();
    let mut bam_src = gt_path.clone();
    bam_src.push("reads.bam");
    let mut bam_tgt = main_path.clone();
    bam_tgt.push("reads.bam");
    move_file(bam_src, bam_tgt, &move_options).unwrap();

    // execute command
    let mut ref_path = gt_path.clone();
    ref_path.push("ref2.fa");

    let mut cmd = Command::main_binary().unwrap();
    cmd.current_dir(&main_path)
       .arg(ref_path)
       .arg("reads.bam")
       .arg("--read-size=5")
       .arg("--skip-bed")
       .arg(format!("--gt-workdir={}", gt_path.to_str().unwrap()))
       .assert().success();

    // check that output files exist in the main directory
    assert!(file_exists_in_folder("reads.bigWig", &main_path));
    assert!(file_exists_in_folder("ref2.tal_5.gtTxt.gz", &main_path));

    // check that genome tools temporary files do not exist in the main directory
    assert!(!file_exists_in_folder("ref2.fa.sa", &main_path));
    assert!(!file_exists_in_folder("ref2.sft.suf", &main_path));
}
<|endoftext|>


<commit_before>//! A channel for sending a single message between asynchronous tasks.

use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use futures_core::{Future, Poll, Async};
use futures_core::task::{self, Waker};
use futures_core::never::Never;

use lock::Lock;

/// A future for a value that will be provided by another asynchronous task.
///
/// This is created by the [`channel`](channel) function.
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct Receiver<T> {
    inner: Arc<Inner<T>>,
}

/// A means of transmitting a single value to another task.
///
/// This is created by the [`channel`](channel) function.
#[derive(Debug)]
pub struct Sender<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Receiver`/`Sender` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
#[derive(Debug)]
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it
    /// appropriately.
    ///
    /// For `Receiver`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Sender` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Receiver`. This is
    /// filled in by `Sender::complete` and read by `Receiver::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Receiver::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Receiver` and the `Sender` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Waker>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Sender::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Waker>>,
}

/// Creates a new one-shot channel for sending values across asynchronous tasks.
///
/// This function is similar to Rust's channel constructor found in the standard library.
/// Two halves are returned, the first of which is a `Sender` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Receiver` which implements the `Future` trait, resolving to the value that
/// was given to the `Sender` handle.
///
/// Each half can be separately owned and sent across tasks.
///
/// # Examples
///
/// ```
/// extern crate futures;
/// extern crate futures_channel;
///
/// use std::thread;
///
/// use futures_channel::oneshot;
/// use futures::*;
///
/// fn main() {
///     let (p, c) = oneshot::channel::<i32>();
///
/// # let t =
///     thread::spawn(|| {
///         let future = c.map(|i| {
///             println!("got: {}", i);
///         });
///         // ...
/// # return future;
///     });
///
///     p.send(3).unwrap();
/// # t.join().unwrap();
/// }
/// ```
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let inner = Arc::new(Inner::new());
    let receiver = Receiver {
        inner: inner.clone(),
    };
    let sender = Sender {
        inner: inner,
    };
    (sender, receiver)
}

impl<T> Inner<T> {
    fn new() -> Inner<T> {
        Inner {
            complete: AtomicBool::new(false),
            data: Lock::new(None),
            rx_task: Lock::new(None),
            tx_task: Lock::new(None),
        }
    }

    fn send(&self, t: T) -> Result<(), T> {
        if self.complete.load(SeqCst) {
            return Err(t)
        }

        // Note that this lock acquisition may fail if the receiver
        // is closed and sets the `complete` flag to true, whereupon
        // the receiver may call `poll()`.
        if let Some(mut slot) = self.data.try_lock() {
            assert!(slot.is_none());
            *slot = Some(t);
            drop(slot);

            // If the receiver called `close()` between the check at the
            // start of the function, and the lock being released, then
            // the receiver may not be around to receive it, so try to
            // pull it back out.
            if self.complete.load(SeqCst) {
                // If lock acquisition fails, then receiver is actually
                // receiving it, so we're good.
                if let Some(mut slot) = self.data.try_lock() {
                    if let Some(t) = slot.take() {
                        return Err(t);
                    }
                }
            }
            Ok(())
        } else {
            // Must have been closed
            Err(t)
        }
    }

    fn poll_cancel(&self, cx: &mut task::Context) -> Poll<(), Never> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Receiver` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Receiver`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = cx.waker().clone();
        match self.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::Pending)
        }
    }

    fn is_canceled(&self) -> bool {
        self.complete.load(SeqCst)
    }

    fn drop_tx(&self) {
        // Flag that we're a completed `Sender` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        //
        // The first case crucially depends on `Lock` using `SeqCst` ordering
        // under the hood. If it instead used `Release` / `Acquire` ordering,
        // then it would not necessarily synchronize with `inner.complete`
        // and deadlock might be possible, as was observed in
        // https://github.com/rust-lang-nursery/futures-rs/pull/219.
        self.complete.store(true, SeqCst);
        if let Some(mut slot) = self.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.wake();
            }
        }
    }

    fn close_rx(&self) {
        // Flag our completion and then attempt to wake up the sender if it's
        // blocked. See comments in `drop` below for more info
        self.complete.store(true, SeqCst);
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }

    fn try_recv(&self) -> Result<Option<T>, Canceled> {
        // If we're complete, either `::close_rx` or `::drop_tx` was called.
        // We can assume a successful send if data is present.
        if self.complete.load(SeqCst) {
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(Some(data.into()));
                }
            }
            // Should there be a different error value or a panic in the case
            // where `self.data.try_lock() == None`?
            Err(Canceled)
        } else {
            Ok(None)
        }
    }

    fn recv(&self, cx: &mut task::Context) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Sender::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.complete.load(SeqCst) {
            done = true;
        } else {
            let task = cx.waker().clone();
            match self.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `Pending`.
        if done || self.complete.load(SeqCst) {
            // If taking the lock fails, the sender will realise that the we're
            // `done` when it checks the `complete` flag on the way out, and will
            // treat the send as a failure.
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(data.into());
                }
            }
            Err(Canceled)
        } else {
            Ok(Async::Pending)
        }
    }

    fn drop_rx(&self) {
        // Indicate to the `Sender` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Sender` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Sender` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Sender` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }
}

impl<T> Sender<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// [`Receiver`](Receiver), that the value provided is the result of the
    /// computation this represents.
    ///
    /// If the value is successfully enqueued for the remote end to receive,
    /// then `Ok(())` is returned. If the receiving end was dropped before
    /// this function was called, however, then `Err` is returned with the value
    /// provided.
    pub fn send(self, t: T) -> Result<(), T> {
        self.inner.send(t)
    }

    /// Polls this `Sender` half to detect whether its associated
    /// [`Receiver`](Receiver) with has been dropped.
    ///
    /// # Return values
    ///
    /// If `Ok(Ready)` is returned then the associated `Receiver` has been
    /// dropped, which means any work required for sending should be canceled.
    ///
    /// If `Ok(Pending)` is returned then the associated `Receiver` is still
    /// alive and may be able to receive a message if sent. The current task,
    /// however, is scheduled to receive a notification if the corresponding
    /// `Receiver` goes away.
    pub fn poll_cancel(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
        self.inner.poll_cancel(cx)
    }

    /// Tests to see whether this `Sender`'s corresponding `Receiver`
    /// has been dropped.
    ///
    /// Unlike [`poll_cancel`](Sender::poll_cancel), this function does not
    /// enqueue a task for wakeup upon cancellation, but merely reports the
    /// current state, which may be subject to concurrent modification.
    pub fn is_canceled(&self) -> bool {
        self.inner.is_canceled()
    }
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        self.inner.drop_tx()
    }
}

/// Error returned from a [`Receiver`](Receiver) when the corresponding
/// [`Sender`](Sender) is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Receiver<T> {
    /// Gracefully close this receiver, preventing any subsequent attempts to
    /// send to it.
    ///
    /// Any `send` operation which happens after this method returns is
    /// guaranteed to fail. After calling this method, you can use
    /// [`Receiver::poll`](Receiver::poll) to determine whether a message had
    /// previously been sent.
    pub fn close(&mut self) {
        self.inner.close_rx()
    }

    /// Attempts to receive a message outside of the context of a task.
    ///
    /// Useful when a [`Context`](Context) is not available such as within a
    /// `Drop` impl.
    ///
    /// Does not schedule a task wakeup or have any other side effects.
    ///
    /// A return value of `None` must be considered immediately stale (out of
    /// date) unless [`::close`](Receiver::close) has been called first.
    ///
    /// Returns an error if the sender was dropped.
    pub fn try_recv(&mut self) -> Result<Option<T>, Canceled> {
        self.inner.try_recv()
    }
}

impl<T> Future for Receiver<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self, cx: &mut task::Context) -> Poll<T, Canceled> {
        self.inner.recv(cx)
    }
}

impl<T> Drop for Receiver<T> {
    fn drop(&mut self) {
        self.inner.drop_rx()
    }
}
<commit_msg>Clean up comment.<commit_after>//! A channel for sending a single message between asynchronous tasks.

use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::error::Error;
use std::fmt;

use futures_core::{Future, Poll, Async};
use futures_core::task::{self, Waker};
use futures_core::never::Never;

use lock::Lock;

/// A future for a value that will be provided by another asynchronous task.
///
/// This is created by the [`channel`](channel) function.
#[must_use = "futures do nothing unless polled"]
#[derive(Debug)]
pub struct Receiver<T> {
    inner: Arc<Inner<T>>,
}

/// A means of transmitting a single value to another task.
///
/// This is created by the [`channel`](channel) function.
#[derive(Debug)]
pub struct Sender<T> {
    inner: Arc<Inner<T>>,
}

/// Internal state of the `Receiver`/`Sender` pair above. This is all used as
/// the internal synchronization between the two for send/recv operations.
#[derive(Debug)]
struct Inner<T> {
    /// Indicates whether this oneshot is complete yet. This is filled in both
    /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it
    /// appropriately.
    ///
    /// For `Receiver`, if this is `true`, then it's guaranteed that `data` is
    /// unlocked and ready to be inspected.
    ///
    /// For `Sender` if this is `true` then the oneshot has gone away and it
    /// can return ready from `poll_cancel`.
    complete: AtomicBool,

    /// The actual data being transferred as part of this `Receiver`. This is
    /// filled in by `Sender::complete` and read by `Receiver::poll`.
    ///
    /// Note that this is protected by `Lock`, but it is in theory safe to
    /// replace with an `UnsafeCell` as it's actually protected by `complete`
    /// above. I wouldn't recommend doing this, however, unless someone is
    /// supremely confident in the various atomic orderings here and there.
    data: Lock<Option<T>>,

    /// Field to store the task which is blocked in `Receiver::poll`.
    ///
    /// This is filled in when a oneshot is polled but not ready yet. Note that
    /// the `Lock` here, unlike in `data` above, is important to resolve races.
    /// Both the `Receiver` and the `Sender` halves understand that if they
    /// can't acquire the lock then some important interference is happening.
    rx_task: Lock<Option<Waker>>,

    /// Like `rx_task` above, except for the task blocked in
    /// `Sender::poll_cancel`. Additionally, `Lock` cannot be `UnsafeCell`.
    tx_task: Lock<Option<Waker>>,
}

/// Creates a new one-shot channel for sending values across asynchronous tasks.
///
/// This function is similar to Rust's channel constructor found in the standard library.
/// Two halves are returned, the first of which is a `Sender` handle, used to
/// signal the end of a computation and provide its value. The second half is a
/// `Receiver` which implements the `Future` trait, resolving to the value that
/// was given to the `Sender` handle.
///
/// Each half can be separately owned and sent across tasks.
///
/// # Examples
///
/// ```
/// extern crate futures;
/// extern crate futures_channel;
///
/// use std::thread;
///
/// use futures_channel::oneshot;
/// use futures::*;
///
/// fn main() {
///     let (p, c) = oneshot::channel::<i32>();
///
/// # let t =
///     thread::spawn(|| {
///         let future = c.map(|i| {
///             println!("got: {}", i);
///         });
///         // ...
/// # return future;
///     });
///
///     p.send(3).unwrap();
/// # t.join().unwrap();
/// }
/// ```
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
    let inner = Arc::new(Inner::new());
    let receiver = Receiver {
        inner: inner.clone(),
    };
    let sender = Sender {
        inner: inner,
    };
    (sender, receiver)
}

impl<T> Inner<T> {
    fn new() -> Inner<T> {
        Inner {
            complete: AtomicBool::new(false),
            data: Lock::new(None),
            rx_task: Lock::new(None),
            tx_task: Lock::new(None),
        }
    }

    fn send(&self, t: T) -> Result<(), T> {
        if self.complete.load(SeqCst) {
            return Err(t)
        }

        // Note that this lock acquisition may fail if the receiver
        // is closed and sets the `complete` flag to true, whereupon
        // the receiver may call `poll()`.
        if let Some(mut slot) = self.data.try_lock() {
            assert!(slot.is_none());
            *slot = Some(t);
            drop(slot);

            // If the receiver called `close()` between the check at the
            // start of the function, and the lock being released, then
            // the receiver may not be around to receive it, so try to
            // pull it back out.
            if self.complete.load(SeqCst) {
                // If lock acquisition fails, then receiver is actually
                // receiving it, so we're good.
                if let Some(mut slot) = self.data.try_lock() {
                    if let Some(t) = slot.take() {
                        return Err(t);
                    }
                }
            }
            Ok(())
        } else {
            // Must have been closed
            Err(t)
        }
    }

    fn poll_cancel(&self, cx: &mut task::Context) -> Poll<(), Never> {
        // Fast path up first, just read the flag and see if our other half is
        // gone. This flag is set both in our destructor and the oneshot
        // destructor, but our destructor hasn't run yet so if it's set then the
        // oneshot is gone.
        if self.complete.load(SeqCst) {
            return Ok(Async::Ready(()))
        }

        // If our other half is not gone then we need to park our current task
        // and move it into the `notify_cancel` slot to get notified when it's
        // actually gone.
        //
        // If `try_lock` fails, then the `Receiver` is in the process of using
        // it, so we can deduce that it's now in the process of going away and
        // hence we're canceled. If it succeeds then we just store our handle.
        //
        // Crucially we then check `oneshot_gone` *again* before we return.
        // While we were storing our handle inside `notify_cancel` the `Receiver`
        // may have been dropped. The first thing it does is set the flag, and
        // if it fails to acquire the lock it assumes that we'll see the flag
        // later on. So... we then try to see the flag later on!
        let handle = cx.waker().clone();
        match self.tx_task.try_lock() {
            Some(mut p) => *p = Some(handle),
            None => return Ok(Async::Ready(())),
        }
        if self.complete.load(SeqCst) {
            Ok(Async::Ready(()))
        } else {
            Ok(Async::Pending)
        }
    }

    fn is_canceled(&self) -> bool {
        self.complete.load(SeqCst)
    }

    fn drop_tx(&self) {
        // Flag that we're a completed `Sender` and try to wake up a receiver.
        // Whether or not we actually stored any data will get picked up and
        // translated to either an item or cancellation.
        //
        // Note that if we fail to acquire the `rx_task` lock then that means
        // we're in one of two situations:
        //
        // 1. The receiver is trying to block in `poll`
        // 2. The receiver is being dropped
        //
        // In the first case it'll check the `complete` flag after it's done
        // blocking to see if it succeeded. In the latter case we don't need to
        // wake up anyone anyway. So in both cases it's ok to ignore the `None`
        // case of `try_lock` and bail out.
        //
        // The first case crucially depends on `Lock` using `SeqCst` ordering
        // under the hood. If it instead used `Release` / `Acquire` ordering,
        // then it would not necessarily synchronize with `inner.complete`
        // and deadlock might be possible, as was observed in
        // https://github.com/rust-lang-nursery/futures-rs/pull/219.
        self.complete.store(true, SeqCst);
        if let Some(mut slot) = self.rx_task.try_lock() {
            if let Some(task) = slot.take() {
                drop(slot);
                task.wake();
            }
        }
    }

    fn close_rx(&self) {
        // Flag our completion and then attempt to wake up the sender if it's
        // blocked. See comments in `drop` below for more info
        self.complete.store(true, SeqCst);
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }

    fn try_recv(&self) -> Result<Option<T>, Canceled> {
        // If we're complete, either `::close_rx` or `::drop_tx` was called.
        // We can assume a successful send if data is present.
        if self.complete.load(SeqCst) {
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(Some(data.into()));
                }
            }
            Err(Canceled)
        } else {
            Ok(None)
        }
    }

    fn recv(&self, cx: &mut task::Context) -> Poll<T, Canceled> {
        let mut done = false;

        // Check to see if some data has arrived. If it hasn't then we need to
        // block our task.
        //
        // Note that the acquisition of the `rx_task` lock might fail below, but
        // the only situation where this can happen is during `Sender::drop`
        // when we are indeed completed already. If that's happening then we
        // know we're completed so keep going.
        if self.complete.load(SeqCst) {
            done = true;
        } else {
            let task = cx.waker().clone();
            match self.rx_task.try_lock() {
                Some(mut slot) => *slot = Some(task),
                None => done = true,
            }
        }

        // If we're `done` via one of the paths above, then look at the data and
        // figure out what the answer is. If, however, we stored `rx_task`
        // successfully above we need to check again if we're completed in case
        // a message was sent while `rx_task` was locked and couldn't notify us
        // otherwise.
        //
        // If we're not done, and we're not complete, though, then we've
        // successfully blocked our task and we return `Pending`.
        if done || self.complete.load(SeqCst) {
            // If taking the lock fails, the sender will realise that the we're
            // `done` when it checks the `complete` flag on the way out, and will
            // treat the send as a failure.
            if let Some(mut slot) = self.data.try_lock() {
                if let Some(data) = slot.take() {
                    return Ok(data.into());
                }
            }
            Err(Canceled)
        } else {
            Ok(Async::Pending)
        }
    }

    fn drop_rx(&self) {
        // Indicate to the `Sender` that we're done, so any future calls to
        // `poll_cancel` are weeded out.
        self.complete.store(true, SeqCst);

        // If we've blocked a task then there's no need for it to stick around,
        // so we need to drop it. If this lock acquisition fails, though, then
        // it's just because our `Sender` is trying to take the task, so we
        // let them take care of that.
        if let Some(mut slot) = self.rx_task.try_lock() {
            let task = slot.take();
            drop(slot);
            drop(task);
        }

        // Finally, if our `Sender` wants to get notified of us going away, it
        // would have stored something in `tx_task`. Here we try to peel that
        // out and unpark it.
        //
        // Note that the `try_lock` here may fail, but only if the `Sender` is
        // in the process of filling in the task. If that happens then we
        // already flagged `complete` and they'll pick that up above.
        if let Some(mut handle) = self.tx_task.try_lock() {
            if let Some(task) = handle.take() {
                drop(handle);
                task.wake()
            }
        }
    }
}

impl<T> Sender<T> {
    /// Completes this oneshot with a successful result.
    ///
    /// This function will consume `self` and indicate to the other end, the
    /// [`Receiver`](Receiver), that the value provided is the result of the
    /// computation this represents.
    ///
    /// If the value is successfully enqueued for the remote end to receive,
    /// then `Ok(())` is returned. If the receiving end was dropped before
    /// this function was called, however, then `Err` is returned with the value
    /// provided.
    pub fn send(self, t: T) -> Result<(), T> {
        self.inner.send(t)
    }

    /// Polls this `Sender` half to detect whether its associated
    /// [`Receiver`](Receiver) with has been dropped.
    ///
    /// # Return values
    ///
    /// If `Ok(Ready)` is returned then the associated `Receiver` has been
    /// dropped, which means any work required for sending should be canceled.
    ///
    /// If `Ok(Pending)` is returned then the associated `Receiver` is still
    /// alive and may be able to receive a message if sent. The current task,
    /// however, is scheduled to receive a notification if the corresponding
    /// `Receiver` goes away.
    pub fn poll_cancel(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
        self.inner.poll_cancel(cx)
    }

    /// Tests to see whether this `Sender`'s corresponding `Receiver`
    /// has been dropped.
    ///
    /// Unlike [`poll_cancel`](Sender::poll_cancel), this function does not
    /// enqueue a task for wakeup upon cancellation, but merely reports the
    /// current state, which may be subject to concurrent modification.
    pub fn is_canceled(&self) -> bool {
        self.inner.is_canceled()
    }
}

impl<T> Drop for Sender<T> {
    fn drop(&mut self) {
        self.inner.drop_tx()
    }
}

/// Error returned from a [`Receiver`](Receiver) when the corresponding
/// [`Sender`](Sender) is dropped.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Canceled;

impl fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "oneshot canceled")
    }
}

impl Error for Canceled {
    fn description(&self) -> &str {
        "oneshot canceled"
    }
}

impl<T> Receiver<T> {
    /// Gracefully close this receiver, preventing any subsequent attempts to
    /// send to it.
    ///
    /// Any `send` operation which happens after this method returns is
    /// guaranteed to fail. After calling this method, you can use
    /// [`Receiver::poll`](Receiver::poll) to determine whether a message had
    /// previously been sent.
    pub fn close(&mut self) {
        self.inner.close_rx()
    }

    /// Attempts to receive a message outside of the context of a task.
    ///
    /// Useful when a [`Context`](Context) is not available such as within a
    /// `Drop` impl.
    ///
    /// Does not schedule a task wakeup or have any other side effects.
    ///
    /// A return value of `None` must be considered immediately stale (out of
    /// date) unless [`::close`](Receiver::close) has been called first.
    ///
    /// Returns an error if the sender was dropped.
    pub fn try_recv(&mut self) -> Result<Option<T>, Canceled> {
        self.inner.try_recv()
    }
}

impl<T> Future for Receiver<T> {
    type Item = T;
    type Error = Canceled;

    fn poll(&mut self, cx: &mut task::Context) -> Poll<T, Canceled> {
        self.inner.recv(cx)
    }
}

impl<T> Drop for Receiver<T> {
    fn drop(&mut self) {
        self.inner.drop_rx()
    }
}
<|endoftext|>


<commit_before>use textwrap::word_separators::{AsciiSpace, WordSeparator};
use textwrap::word_splitters::{HyphenSplitter, NoHyphenation, WordSplitter};
use textwrap::wrap_algorithms::{FirstFit, WrapAlgorithm};
use textwrap::Options;

/// Cleaned up type name.
fn type_name<T: ?Sized>(_val: &T) -> String {
    std::any::type_name::<T>().replace("alloc::boxed::Box", "Box")
}

#[test]
#[cfg(not(feature = "smawk"))]
#[cfg(not(feature = "unicode-linebreak"))]
fn static_hyphensplitter() {
    // Inferring the full type.
    let options = Options::new(10);
    assert_eq!(
        type_name(&options),
        format!(
            "textwrap::Options<{}, {}, {}>",
            "textwrap::wrap_algorithms::FirstFit",
            "textwrap::word_separators::AsciiSpace",
            "textwrap::word_splitters::HyphenSplitter"
        )
    );

    // Inferring part of the type.
    let options: Options<_, _, HyphenSplitter> = Options::new(10);
    assert_eq!(
        type_name(&options),
        format!(
            "textwrap::Options<{}, {}, {}>",
            "textwrap::wrap_algorithms::FirstFit",
            "textwrap::word_separators::AsciiSpace",
            "textwrap::word_splitters::HyphenSplitter"
        )
    );

    // Explicitly making all parameters inferred.
    let options: Options<_, _, _> = Options::new(10);
    assert_eq!(
        type_name(&options),
        format!(
            "textwrap::Options<{}, {}, {}>",
            "textwrap::wrap_algorithms::FirstFit",
            "textwrap::word_separators::AsciiSpace",
            "textwrap::word_splitters::HyphenSplitter"
        )
    );
}

#[test]
fn box_static_nohyphenation() {
    // Inferred static type.
    let options = Options::new(10)
        .wrap_algorithm(Box::new(FirstFit))
        .word_splitter(Box::new(NoHyphenation))
        .word_separator(Box::new(AsciiSpace));
    assert_eq!(
        type_name(&options),
        format!(
            "textwrap::Options<{}, {}, {}>",
            "Box<textwrap::wrap_algorithms::FirstFit>",
            "Box<textwrap::word_separators::AsciiSpace>",
            "Box<textwrap::word_splitters::NoHyphenation>"
        )
    );
}

#[test]
fn box_dyn_wordsplitter() {
    // Inferred dynamic type due to default type parameter.
    let options = Options::new(10)
        .wrap_algorithm(Box::new(FirstFit) as Box<dyn WrapAlgorithm>)
        .word_splitter(Box::new(HyphenSplitter) as Box<dyn WordSplitter>)
        .word_separator(Box::new(AsciiSpace) as Box<dyn WordSeparator>);
    assert_eq!(
        type_name(&options),
        format!(
            "textwrap::Options<{}, {}, {}>",
            "Box<dyn textwrap::wrap_algorithms::WrapAlgorithm>",
            "Box<dyn textwrap::word_separators::WordSeparator>",
            "Box<dyn textwrap::word_splitters::WordSplitter>"
        )
    );
}
<commit_msg>Remove `traits` test<commit_after><|endoftext|>