<commit_before>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;

pub struct PriorityQueue <T: Copy Ord>{
    priv data: ~[T],
}

impl <T: Copy Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftdown(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftup(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftdown_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftdown(n) }; // purity-checking workaround
        }
        q
    }

    priv fn siftup(&mut self, start: uint, pos: uint) {
        let mut pos = pos;
        let new = self.data[pos];

        while pos > start {
            let parent = (pos - 1) >> 1;
            if new > self.data[parent] {
                self.data[pos] = self.data[parent];
                pos = parent;
                loop
            }
            break
        }
        self.data[pos] = new;
    }

    priv fn siftdown_range(&mut self, pos: uint, end: uint) {
        let mut pos = pos;
        let start = pos;
        let new = self.data[pos];

        let mut child = 2 * pos + 1;
        while child < end {
            let right = child + 1;
            if right < end && !(self.data[child] > self.data[right]) {
                child = right;
            }
            self.data[pos] = self.data[child];
            pos = child;
            child = 2 * pos + 1;
        }
        self.data[pos] = new;
        self.siftup(start, pos);
    }

    priv fn siftdown(&mut self, pos: uint) {
        self.siftdown_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<commit_msg>priority_queue: replace copies with moves<commit_after>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;
use ptr::addr_of;

#[abi = "rust-intrinsic"]
extern "C" mod rusti {
    fn move_val_init<T>(dst: &mut T, -src: T);
}

pub struct PriorityQueue <T: Ord>{
    priv data: ~[T],
}

impl <T: Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftdown(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftup(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftdown_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftdown(n) }; // purity-checking workaround
        }
        q
    }

    // The implementations of siftup and siftdown use unsafe blocks in order to
    // move an element out of the vector (leaving behind a junk element), shift
    // along the others and move it back into the vector over the junk element.
    // This reduces the constant factor compared to using swaps, which involves
    // twice as many moves.

    priv fn siftup(&mut self, start: uint, pos: uint) unsafe {
        let mut pos = pos;
        let new = move *addr_of(&self.data[pos]);

        while pos > start {
            let parent = (pos - 1) >> 1;
            if new > self.data[parent] {
                rusti::move_val_init(&mut self.data[pos],
                                     move *addr_of(&self.data[parent]));
                pos = parent;
                loop
            }
            break
        }
        rusti::move_val_init(&mut self.data[pos], move new);
    }

    priv fn siftdown_range(&mut self, pos: uint, end: uint) unsafe {
        let mut pos = pos;
        let start = pos;
        let new = move *addr_of(&self.data[pos]);

        let mut child = 2 * pos + 1;
        while child < end {
            let right = child + 1;
            if right < end && !(self.data[child] > self.data[right]) {
                child = right;
            }
            rusti::move_val_init(&mut self.data[pos],
                                 move *addr_of(&self.data[child]));
            pos = child;
            child = 2 * pos + 1;
        }
        rusti::move_val_init(&mut self.data[pos], move new);
        self.siftup(start, pos);
    }

    priv fn siftdown(&mut self, pos: uint) {
        self.siftdown_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<|endoftext|>


<commit_before>use library;

pub trait TranslateToGlib {
    fn translate_to_glib(&self, library: &library::Library, in_trait: bool) -> String;
}

impl TranslateToGlib for library::Parameter {
    fn translate_to_glib(&self, _library: &library::Library, in_trait: bool) -> String {
        if self.instance_parameter {
            let upcast_str = if in_trait { ".upcast()" } else { "" };
            format!("self{}.to_glib_none().0", upcast_str)
        } else {
            format!("TODO:{}", self.name)
        }
    }
}
<commit_msg>Generate other parameters<commit_after>use analysis::type_kind::{TypeKind, ToTypeKind};
use library;

pub trait TranslateToGlib {
    fn translate_to_glib(&self, library: &library::Library, in_trait: bool) -> String;
}

impl TranslateToGlib for library::Parameter {
    fn translate_to_glib(&self, library: &library::Library, in_trait: bool) -> String {
        if self.instance_parameter {
            let upcast_str = if in_trait { ".upcast()" } else { "" };
            format!("self{}.to_glib_none().0", upcast_str)
        } else {
            let kind = library.type_(self.typ).to_type_kind(library);
            match kind {
                TypeKind::Converted => format_parameter(&self.name, "to_glib()"),
                TypeKind::Pointer => format_parameter(&self.name, "to_glib_none().0"),
                TypeKind::Direct |
                    TypeKind::Enumeration => self.name.clone(),
                TypeKind::Object |
                    TypeKind::Widget => to_glib_xxx(&self.name, self.transfer),
                _ => format!("TODO:{}", self.name)
            }
        }
    }
}

fn format_parameter(name: &str, convert: &str) -> String {
    format!("{}.{}", name, convert)
}

fn to_glib_xxx(name: &str, transfer: library::Transfer) -> String {
    use library::Transfer::*;
    match transfer {
        None => format_parameter(name, "to_glib_none().0"),
        Full => format_parameter(name, "to_glib_full().0"),
        Container => format!("TODO:container {}", name),
    }
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ReadStream, Stream, StreamProducer};
use flac::metadata;
use flac::metadata::VorbisComment;

use std::env;
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <input>
       metadata comments [options] <input>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_input: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
}

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    println!("Sample rate: {} Hz", info.sample_rate);
  }

  if no_flags || args.flag_channels {
    println!("Number of channels: {}", info.channels);
  }

  if no_flags || args.flag_bits_per_sample {
    println!("Bits per sample: {}", info.bits_per_sample);
  }

  if no_flags || args.flag_total_samples {
    println!("Total samples: {}", info.total_samples);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    println!("MD5 sum: {}", md5);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment) {
  let mut index = 1;

  println!("Vendor String: {}", vorbis_comment.vendor_string);
  println!("Number of Comments: {}", vorbis_comment.comments.len());

  for comment in &vorbis_comment.comments {
    println!("  {}: \"{}\" = {}", index, comment.0, comment.1);

    index += 1;
  }
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  let stream = Stream::<ReadStream<File>>::from_file(&args.arg_input)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          print_vorbis_comments(v)
        }
      }
      _                                    => continue,
    }
  }
}
<commit_msg>Add new options to the Arguments struct<commit_after>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ReadStream, Stream, StreamProducer};
use flac::metadata;
use flac::metadata::VorbisComment;

use std::env;
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <input>
       metadata comments [options] <input>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_input: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
  flag_vendor: bool,
  flag_name: Option<String>,
}

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    println!("Sample rate: {} Hz", info.sample_rate);
  }

  if no_flags || args.flag_channels {
    println!("Number of channels: {}", info.channels);
  }

  if no_flags || args.flag_bits_per_sample {
    println!("Bits per sample: {}", info.bits_per_sample);
  }

  if no_flags || args.flag_total_samples {
    println!("Total samples: {}", info.total_samples);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    println!("MD5 sum: {}", md5);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment) {
  let mut index = 1;

  println!("Vendor String: {}", vorbis_comment.vendor_string);
  println!("Number of Comments: {}", vorbis_comment.comments.len());

  for comment in &vorbis_comment.comments {
    println!("  {}: \"{}\" = {}", index, comment.0, comment.1);

    index += 1;
  }
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  let stream = Stream::<ReadStream<File>>::from_file(&args.arg_input)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          print_vorbis_comments(v)
        }
      }
      _                                    => continue,
    }
  }
}
<|endoftext|>


<commit_before>use nom::{self, IResult, Needed};

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug, Eq, PartialEq)]
pub enum ErrorKind {
  IO(io::ErrorKind),
  Incomplete(usize),
  Continue,
  EndOfInput,
  Unknown,
  // Parser Error
  HeaderParser,
  MetadataHeaderParser,
  StreamInfoParser,
  PaddingParser,
  ApplicationParser,
  SeekTableParser,
  VorbisCommentParser,
  CueSheetParser,
  PictureParser,
  UnknownParser,
  FrameFooterParser,
  // Invalid Error
  InvalidBlockType,
  InvalidCRC8,
  InvalidCRC16,
  // Not Found
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    nom::be_u32(input).map_err(to_custom_error!(Unknown))
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<commit_msg>Add more error types for parsers and invalidations<commit_after>use nom::{self, IResult, Needed};

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::StreamProducer;

#[derive(Debug, Eq, PartialEq)]
pub enum ErrorKind {
  IO(io::ErrorKind),
  Incomplete(usize),
  Continue,
  EndOfInput,
  Unknown,
  // Parser Error
  HeaderParser,
  MetadataHeaderParser,
  StreamInfoParser,
  PaddingParser,
  ApplicationParser,
  SeekTableParser,
  VorbisCommentParser,
  CueSheetParser,
  PictureParser,
  UnknownParser,
  BlockingStrategyParser,
  BlockingSampleParser,
  ChannelBitsParser,
  UTF8HeaderParser,
  UTF8BodyParser,
  CRC8Parser,
  FrameFooterParser,
  // Invalid Error
  InvalidBlockType,
  InvalidSyncCode,
  InvalidBlockSample,
  InvalidChannelBits,
  InvalidUTF8,
  InvalidCRC8,
  InvalidCRC16,
  // Not Found
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    nom::be_u32(input).map_err(to_custom_error!(Unknown))
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<|endoftext|>


<commit_before>use super::*;

#[cfg(all(feature = "model", feature = "utils"))]
use std::result::Result as StdResult;
#[cfg(all(feature = "cache", feature = "utils"))]
use std::error::Error as StdError;
#[cfg(all(feature = "model", feature = "utils"))]
use std::str::FromStr;
#[cfg(all(feature = "model", feature = "utils"))]
use std::fmt;
#[cfg(any(all(feature = "cache", feature = "utils"), all(feature = "model", feature = "utils")))]
use utils;

/// Allows something - such as a channel or role - to be mentioned in a message.
pub trait Mentionable {
    /// Creates a mentionable string, that will be able to notify and/or create
    /// a link to the item.
    fn mention(&self) -> String;
}

impl Mentionable for ChannelId {
    fn mention(&self) -> String { format!("<#{}>", self.0) }
}

impl Mentionable for Channel {
    fn mention(&self) -> String {
        match *self {
            Channel::Guild(ref x) => format!("<#{}>", x.read().unwrap().id.0),
            Channel::Private(ref x) => format!("<#{}>", x.read().unwrap().id.0),
            Channel::Group(ref x) => format!("<#{}>", x.read().unwrap().channel_id.0),
        }
    }
}

impl Mentionable for Emoji {
    fn mention(&self) -> String { format!("<:{}:{}>", self.name, self.id.0) }
}

impl Mentionable for Member {
    fn mention(&self) -> String { format!("<@{}>", self.user.read().unwrap().id.0) }
}

impl Mentionable for RoleId {
    fn mention(&self) -> String { format!("<@&{}>", self.0) }
}

impl Mentionable for Role {
    fn mention(&self) -> String { format!("<@&{}>", self.id.0) }
}

impl Mentionable for UserId {
    fn mention(&self) -> String { format!("<@{}>", self.0) }
}

impl Mentionable for User {
    fn mention(&self) -> String { format!("<@{}>", self.id.0) }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum UserParseError {
    NotPresentInCache,
    InvalidUsername
}

impl fmt::Display for UserParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for UserParseError {
    fn description(&self) -> &str {
        use self::UserParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidUsername => "invalid username"
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl FromStr for User {
    type Err = UserParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_username(s) {
            Some(x) => {
                match UserId(x as u64).find() {
                    Some(user) => Ok(user.read().unwrap().clone()),
                    _ => Err(UserParseError::NotPresentInCache),
                }
            },
            _ => Err(UserParseError::InvalidUsername),
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum UserIdParseError {
    NotPresentInCache,
}

impl fmt::Display for UserIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for UserIdParseError {
    fn description(&self) -> &str {
        use self::UserIdParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for UserId {
    type Err = UserIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        utils::parse_username(s).ok_or_else(|| UserIdParseError::NotPresentInCache).map(UserId)
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum RoleParseError {
    NotPresentInCache,
    InvalidRole,
}

impl fmt::Display for RoleParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for RoleParseError {
    fn description(&self) -> &str {
        use self::RoleParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidRole => "invalid role"
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl FromStr for Role {
    type Err = RoleParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_role(s) {
            Some(x) => {
                match RoleId(x).find() {
                    Some(user) => Ok(user),
                    _ => Err(RoleParseError::NotPresentInCache),
                }
            },
            _ => Err(RoleParseError::InvalidRole),
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum RoleIdParseError {
    NotPresentInCache,
}

impl fmt::Display for RoleIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for RoleIdParseError {
    fn description(&self) -> &str {
        use self::RoleIdParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for RoleId {
    type Err = RoleIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        utils::parse_role(s).ok_or_else(|| RoleIdParseError::NotPresentInCache).map(RoleId)
    }
}

/// A version of an emoji used only when solely the Id and name are known.
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct EmojiIdentifier {
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl EmojiIdentifier {
    /// Generates a URL to the emoji's image.
    #[inline]
    pub fn url(&self) -> String { format!(cdn!("/emojis/{}.png"), self.id) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for EmojiIdentifier {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> { utils::parse_emoji(s).ok_or_else(|| ()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for ChannelId {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        utils::parse_channel(s).ok_or_else(|| ()).map(ChannelId)
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Channel {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        match utils::parse_channel(s) {
            Some(x) => {
                match ChannelId(x).find() {
                    Some(channel) => Ok(channel),
                    _ => Err(()),
                }
            },
            _ => Err(()),
        }
    }
}

/// A component that was affected during a service incident.
///
/// This is pulled from the Discord status page.
#[derive(Clone, Debug, Deserialize)]
pub struct AffectedComponent {
    pub name: String,
}

/// An incident retrieved from the Discord status page.
///
/// This is not necessarily a representation of an ongoing incident.
#[derive(Clone, Debug, Deserialize)]
pub struct Incident {
    pub created_at: String,
    pub id: String,
    pub impact: String,
    pub incident_updates: Vec<IncidentUpdate>,
    pub monitoring_at: Option<String>,
    pub name: String,
    pub page_id: String,
    pub resolved_at: Option<String>,
    pub short_link: String,
    pub status: String,
    pub updated_at: String,
}

/// An update to an incident from the Discord status page.
///
/// This will typically state what new information has been discovered about an
/// incident.
#[derive(Clone, Debug, Deserialize)]
pub struct IncidentUpdate {
    pub affected_components: Vec<AffectedComponent>,
    pub body: String,
    pub created_at: String,
    pub display_at: String,
    pub id: String,
    pub incident_id: String,
    pub status: IncidentStatus,
    pub updated_at: String,
}

/// The type of status update during a service incident.
#[derive(Copy, Clone, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentStatus {
    Identified,
    Investigating,
    Monitoring,
    Postmortem,
    Resolved,
}

/// A Discord status maintenance message. This can be either for active
/// maintenances or for scheduled maintenances.
#[derive(Clone, Debug, Deserialize)]
pub struct Maintenance {
    pub description: String,
    pub id: String,
    pub name: String,
    pub start: String,
    pub stop: String,
}
<commit_msg>Cfg the display impls as well<commit_after>use super::*;

#[cfg(all(feature = "model", feature = "utils"))]
use std::result::Result as StdResult;
#[cfg(all(feature = "cache", feature = "utils"))]
use std::error::Error as StdError;
#[cfg(all(feature = "model", feature = "utils"))]
use std::str::FromStr;
#[cfg(all(feature = "model", feature = "utils"))]
use std::fmt;
#[cfg(any(all(feature = "cache", feature = "utils"), all(feature = "model", feature = "utils")))]
use utils;

/// Allows something - such as a channel or role - to be mentioned in a message.
pub trait Mentionable {
    /// Creates a mentionable string, that will be able to notify and/or create
    /// a link to the item.
    fn mention(&self) -> String;
}

impl Mentionable for ChannelId {
    fn mention(&self) -> String { format!("<#{}>", self.0) }
}

impl Mentionable for Channel {
    fn mention(&self) -> String {
        match *self {
            Channel::Guild(ref x) => format!("<#{}>", x.read().unwrap().id.0),
            Channel::Private(ref x) => format!("<#{}>", x.read().unwrap().id.0),
            Channel::Group(ref x) => format!("<#{}>", x.read().unwrap().channel_id.0),
        }
    }
}

impl Mentionable for Emoji {
    fn mention(&self) -> String { format!("<:{}:{}>", self.name, self.id.0) }
}

impl Mentionable for Member {
    fn mention(&self) -> String { format!("<@{}>", self.user.read().unwrap().id.0) }
}

impl Mentionable for RoleId {
    fn mention(&self) -> String { format!("<@&{}>", self.0) }
}

impl Mentionable for Role {
    fn mention(&self) -> String { format!("<@&{}>", self.id.0) }
}

impl Mentionable for UserId {
    fn mention(&self) -> String { format!("<@{}>", self.0) }
}

impl Mentionable for User {
    fn mention(&self) -> String { format!("<@{}>", self.id.0) }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum UserParseError {
    NotPresentInCache,
    InvalidUsername
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for UserParseError {
    fn description(&self) -> &str {
        use self::UserParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidUsername => "invalid username"
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl FromStr for User {
    type Err = UserParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_username(s) {
            Some(x) => {
                match UserId(x as u64).find() {
                    Some(user) => Ok(user.read().unwrap().clone()),
                    _ => Err(UserParseError::NotPresentInCache),
                }
            },
            _ => Err(UserParseError::InvalidUsername),
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum UserIdParseError {
    NotPresentInCache,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for UserIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for UserIdParseError {
    fn description(&self) -> &str {
        use self::UserIdParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for UserId {
    type Err = UserIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        utils::parse_username(s).ok_or_else(|| UserIdParseError::NotPresentInCache).map(UserId)
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum RoleParseError {
    NotPresentInCache,
    InvalidRole,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for RoleParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for RoleParseError {
    fn description(&self) -> &str {
        use self::RoleParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
            InvalidRole => "invalid role"
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl FromStr for Role {
    type Err = RoleParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        match utils::parse_role(s) {
            Some(x) => {
                match RoleId(x).find() {
                    Some(user) => Ok(user),
                    _ => Err(RoleParseError::NotPresentInCache),
                }
            },
            _ => Err(RoleParseError::InvalidRole),
        }
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
#[derive(Debug)]
pub enum RoleIdParseError {
    NotPresentInCache,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl fmt::Display for RoleIdParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

#[cfg(all(feature = "cache", feature = "utils"))]
impl StdError for RoleIdParseError {
    fn description(&self) -> &str {
        use self::RoleIdParseError::*;

        match *self {
            NotPresentInCache => "not present in cache",
        }
    }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for RoleId {
    type Err = RoleIdParseError;

    fn from_str(s: &str) -> StdResult<Self, Self::Err> {
        utils::parse_role(s).ok_or_else(|| RoleIdParseError::NotPresentInCache).map(RoleId)
    }
}

/// A version of an emoji used only when solely the Id and name are known.
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct EmojiIdentifier {
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
}

#[cfg(all(feature = "model", feature = "utils"))]
impl EmojiIdentifier {
    /// Generates a URL to the emoji's image.
    #[inline]
    pub fn url(&self) -> String { format!(cdn!("/emojis/{}.png"), self.id) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for EmojiIdentifier {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> { utils::parse_emoji(s).ok_or_else(|| ()) }
}

#[cfg(all(feature = "model", feature = "utils"))]
impl FromStr for ChannelId {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        utils::parse_channel(s).ok_or_else(|| ()).map(ChannelId)
    }
}

#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
impl FromStr for Channel {
    type Err = ();

    fn from_str(s: &str) -> StdResult<Self, ()> {
        match utils::parse_channel(s) {
            Some(x) => {
                match ChannelId(x).find() {
                    Some(channel) => Ok(channel),
                    _ => Err(()),
                }
            },
            _ => Err(()),
        }
    }
}

/// A component that was affected during a service incident.
///
/// This is pulled from the Discord status page.
#[derive(Clone, Debug, Deserialize)]
pub struct AffectedComponent {
    pub name: String,
}

/// An incident retrieved from the Discord status page.
///
/// This is not necessarily a representation of an ongoing incident.
#[derive(Clone, Debug, Deserialize)]
pub struct Incident {
    pub created_at: String,
    pub id: String,
    pub impact: String,
    pub incident_updates: Vec<IncidentUpdate>,
    pub monitoring_at: Option<String>,
    pub name: String,
    pub page_id: String,
    pub resolved_at: Option<String>,
    pub short_link: String,
    pub status: String,
    pub updated_at: String,
}

/// An update to an incident from the Discord status page.
///
/// This will typically state what new information has been discovered about an
/// incident.
#[derive(Clone, Debug, Deserialize)]
pub struct IncidentUpdate {
    pub affected_components: Vec<AffectedComponent>,
    pub body: String,
    pub created_at: String,
    pub display_at: String,
    pub id: String,
    pub incident_id: String,
    pub status: IncidentStatus,
    pub updated_at: String,
}

/// The type of status update during a service incident.
#[derive(Copy, Clone, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentStatus {
    Identified,
    Investigating,
    Monitoring,
    Postmortem,
    Resolved,
}

/// A Discord status maintenance message. This can be either for active
/// maintenances or for scheduled maintenances.
#[derive(Clone, Debug, Deserialize)]
pub struct Maintenance {
    pub description: String,
    pub id: String,
    pub name: String,
    pub start: String,
    pub stop: String,
}
<|endoftext|>


<commit_before>extern crate ggez;
use ggez::conf;
use ggez::game;
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::timer;
use std::time::Duration;

// First we make a structure to contain the game's state
struct MainState {
    image1: graphics::Image,
    image2: graphics::Image,
}

// Then we implement the `ggez::game::GameState` trait on it, which
// requires callbacks for creating the game state, updating it each
// frame, and drawing it.
//
// The `GameState` trait also contains callbacks for event handling
// that you can override if you wish, but the defaults are fine.
impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {

        let image1 = graphics::Image::new(ctx, "resources/dragon1.png")?;
        let image2 = graphics::Image::new(ctx, "resources/dragon2.png")?;
        let s = MainState {
            image1: image1,
            image2: image2,
        };
        Ok(s)
    }
}

impl game::EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);
        graphics::draw(ctx, &mut self.image1, None, None);
        let dst = graphics::Rect::new(100.0, 100.0, 0.0, 0.0);
        graphics::draw(ctx, &mut self.image2, None, Some(dst));
        graphics::present(ctx);
        timer::sleep_until_next_frame(ctx, 60);
        Ok(())
    }
}

// Now our main function, which does three things:
//
// * First, create a new `ggez::conf::Conf`
// object which contains configuration info on things such
// as screen resolution and window title,
// * Second, create a `ggez::game::Game` object which will
// do the work of creating our MainState and running our game,
// * then just call `game.run()` which runs the `Game` mainloop.
pub fn main() {
    let c = conf::Conf::new();
    let ctx = &mut Context::load_from_conf("helloworld", c).unwrap();
    let state = &mut MainState::new(ctx).unwrap();
    if let Err(e) = game::run(ctx, state) {
        println!("Error encountered: {}", e);
    } else {
        println!("Game exited cleanly.");
    }
}
<commit_msg>Very basic performance testing.<commit_after>extern crate ggez;
use ggez::conf;
use ggez::game;
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::timer;
use std::time::Duration;

// First we make a structure to contain the game's state
struct MainState {
    image1: graphics::Image,
    image2: graphics::Image,
    zoomlevel: f32,
}

// Then we implement the `ggez::game::GameState` trait on it, which
// requires callbacks for creating the game state, updating it each
// frame, and drawing it.
//
// The `GameState` trait also contains callbacks for event handling
// that you can override if you wish, but the defaults are fine.
impl MainState {
    fn new(ctx: &mut Context) -> GameResult<MainState> {

        let image1 = graphics::Image::new(ctx, "resources/dragon1.png")?;
        let image2 = graphics::Image::new(ctx, "resources/dragon2.png")?;
        let s = MainState {
            image1: image1,
            image2: image2,
            zoomlevel: 1.0,
        };

        graphics::set_screen_coordinates(ctx, -s.zoomlevel, s.zoomlevel, s.zoomlevel, -s.zoomlevel);
        Ok(s)
    }
}

impl game::EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        graphics::set_screen_coordinates(ctx, -self.zoomlevel, self.zoomlevel, self.zoomlevel, -self.zoomlevel);
        self.zoomlevel += 1.0;
        println!("Updating");
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        println!("Starting draw");
        // graphics::clear(ctx);
        // graphics::draw(ctx, &mut self.image1, None, None);
        // let dst = graphics::Rect::new(1.0, 1.0, 0.0, 0.0);
        // graphics::draw(ctx, &mut self.image2, None, Some(dst));
        graphics::present(ctx);
        println!("Approx FPS: {}", timer::get_fps(ctx));
        // timer::sleep_until_next_frame(ctx, 60);
        Ok(())
    }
}

// Now our main function, which does three things:
//
// * First, create a new `ggez::conf::Conf`
// object which contains configuration info on things such
// as screen resolution and window title,
// * Second, create a `ggez::game::Game` object which will
// do the work of creating our MainState and running our game,
// * then just call `game.run()` which runs the `Game` mainloop.
pub fn main() {
    let c = conf::Conf::new();
    let ctx = &mut Context::load_from_conf("helloworld", c).unwrap();
    let state = &mut MainState::new(ctx).unwrap();
    if let Err(e) = game::run(ctx, state) {
        println!("Error encountered: {}", e);
    } else {
        println!("Game exited cleanly.");
    }
}
<|endoftext|>


<commit_before>extern crate serde_json;
extern crate regex;

pub mod common;
pub mod did;
pub mod pool;
pub mod wallet;
pub mod ledger;
pub mod payment_address;

use self::regex::Regex;

use command_executor::{CommandContext, CommandParams};

use std;
use libindy::ledger::Ledger;

pub fn get_str_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<&'a str, ()> {
    match params.get(name) {
        Some(v) if v == "" => {
            println_err!("Required \"{}\" parameter is empty.", name);
            Err(())
        }
        Some(v) => Ok(v.as_str()),
        None => {
            println_err!("No required \"{}\" parameter present.", name);
            Err(())
        }
    }
}

pub fn get_opt_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    match params.get(key) {
        Some(v) if v == "" => {
            println_err!("Optional parameter \"{}\" is empty.", key);
            Err(())
        }
        Some(v) => Ok(Some(v.as_str())),
        None => Ok(None)
    }
}

pub fn get_opt_empty_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    Ok(params.get(key).map(|v| v.as_str()))
}

pub fn _get_int_param<T>(name: &str, params: &CommandParams) -> Result<T, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    match params.get(name) {
        Some(v) => {
            Ok(v.parse::<T>().map_err(|err|
                println_err!("Can't parse integer parameter \"{}\": err {}", name, err))?)
        }
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_number_param<T>(key: &str, params: &CommandParams) -> Result<Option<T>, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    let res = match params.get(key) {
        Some(value) => Some(value.parse::<T>().map_err(|err|
            println_err!("Can't parse integer parameter \"{}\": err {}", key, err))?),
        None => None
    };
    Ok(res)
}

pub fn get_bool_param(key: &str, params: &CommandParams) -> Result<bool, ()> {
    match params.get(key) {
        Some(value) => Ok(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", key);
            Err(())
        }
    }
}

pub fn get_opt_bool_param(key: &str, params: &CommandParams) -> Result<Option<bool>, ()> {
    match params.get(key) {
        Some(value) => Ok(Some(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?)),
        None => Ok(None)
    }
}

pub fn get_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<&'a str>, ()> {
    match params.get(name) {
        None => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) if v.is_empty() => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) => Ok(v.split(",").collect::<Vec<&'a str>>())
    }
}

pub fn get_opt_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<&'a str>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<&'a str>::new()))
            } else {
                Ok(Some(v.split(",").collect::<Vec<&'a str>>()))
            },
        None => Ok(None)
    }
}

pub fn get_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<serde_json::Value, ()> {
    match params.get(name) {
        Some(v) => Ok(serde_json::from_str(v).map_err(|err|
            println_err!("Can't parse object parameter \"{}\": err {}", name, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<serde_json::Value>, ()> {
    match params.get(name) {
        Some(_) => Ok(Some(get_object_param(name, params)?)),
        None => Ok(None)
    }
}

fn extract_array_tuples<'a>(param: &'a str) -> Vec<String> {
    let re = Regex::new(r#"\(([^\(\)]+)\),?"#).unwrap();
    re.captures_iter(param).map(|c| c[1].to_string()).collect::<Vec<String>>()
}

pub fn get_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<String>, ()> {
    match params.get(name) {
        Some(v) if !v.is_empty() => {
            let tuples = extract_array_tuples(v);
            if tuples.len() == 0 {
                Err(println_err!("Parameter \"{}\" has invalid format", name))
            } else {
                Ok(tuples)
            }
        }
        _ => Err(println_err!("No required \"{}\" parameter present", name))
    }
}

pub fn get_opt_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<String>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<String>::new()))
            } else {
                Ok(Some(extract_array_tuples(v)))
            },
        None => Ok(None)
    }
}

pub fn ensure_active_did(ctx: &CommandContext) -> Result<String, ()> {
    match ctx.get_string_value("ACTIVE_DID") {
        Some(did) => Ok(did),
        None => Err(println_err!("There is no active did"))
    }
}

pub fn get_active_did(ctx: &CommandContext) -> Option<String> {
    ctx.get_string_value("ACTIVE_DID")
}

pub fn set_active_did(ctx: &CommandContext, did: Option<String>) {
    ctx.set_string_value("ACTIVE_DID", did.clone());
    ctx.set_sub_prompt(3, did.map(|did| format!("did({}...{})", &did[..3], &did[did.len() - 3..])));
}

pub fn ensure_opened_wallet_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("OPENED_WALLET_HANDLE") {
        Some(wallet_handle) => Ok(wallet_handle),
        None => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn ensure_opened_wallet(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn get_opened_wallet(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_opened_wallet(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("OPENED_WALLET_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("OPENED_WALLET_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(2, value.map(|value| format!("wallet({})", value.1)));
}

pub fn ensure_connected_pool_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("CONNECTED_POOL_HANDLE") {
        Some(pool_handle) => Ok(pool_handle),
        None => Err(println_err!("There is no opened pool now"))
    }
}

pub fn ensure_connected_pool(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened pool now"))
    }
}

pub fn get_connected_pool(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_connected_pool(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("CONNECTED_POOL_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("CONNECTED_POOL_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(1, value.map(|value| format!("pool({})", value.1)));
}

#[cfg(test)]
pub fn submit_retry<F, T, E>(ctx: &CommandContext, request: &str, parser: F) -> Result<(), ()>
    where F: Fn(&str) -> Result<T, E> {
    const SUBMIT_RETRY_CNT: usize = 3;
    const SUBMIT_TIMEOUT_SEC: u64 = 2;

    let pool_handle = ensure_connected_pool_handle(ctx).unwrap();

    for _ in 0..SUBMIT_RETRY_CNT {
        let response = Ledger::submit_request(pool_handle, request).unwrap();
        if parser(&response).is_ok() {
            return Ok(());
        }
        ::std::thread::sleep(::std::time::Duration::from_secs(SUBMIT_TIMEOUT_SEC));
    }

    return Err(());
}<commit_msg>Fix warning<commit_after>extern crate serde_json;
extern crate regex;

pub mod common;
pub mod did;
pub mod pool;
pub mod wallet;
pub mod ledger;
pub mod payment_address;

use self::regex::Regex;

use command_executor::{CommandContext, CommandParams};

use std;

pub fn get_str_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<&'a str, ()> {
    match params.get(name) {
        Some(v) if v == "" => {
            println_err!("Required \"{}\" parameter is empty.", name);
            Err(())
        }
        Some(v) => Ok(v.as_str()),
        None => {
            println_err!("No required \"{}\" parameter present.", name);
            Err(())
        }
    }
}

pub fn get_opt_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    match params.get(key) {
        Some(v) if v == "" => {
            println_err!("Optional parameter \"{}\" is empty.", key);
            Err(())
        }
        Some(v) => Ok(Some(v.as_str())),
        None => Ok(None)
    }
}

pub fn get_opt_empty_str_param<'a>(key: &'a str, params: &'a CommandParams) -> Result<Option<&'a str>, ()> {
    Ok(params.get(key).map(|v| v.as_str()))
}

pub fn _get_int_param<T>(name: &str, params: &CommandParams) -> Result<T, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    match params.get(name) {
        Some(v) => {
            Ok(v.parse::<T>().map_err(|err|
                println_err!("Can't parse integer parameter \"{}\": err {}", name, err))?)
        }
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_number_param<T>(key: &str, params: &CommandParams) -> Result<Option<T>, ()>
    where T: std::str::FromStr, <T as std::str::FromStr>::Err: std::fmt::Display {
    let res = match params.get(key) {
        Some(value) => Some(value.parse::<T>().map_err(|err|
            println_err!("Can't parse integer parameter \"{}\": err {}", key, err))?),
        None => None
    };
    Ok(res)
}

pub fn get_bool_param(key: &str, params: &CommandParams) -> Result<bool, ()> {
    match params.get(key) {
        Some(value) => Ok(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", key);
            Err(())
        }
    }
}

pub fn get_opt_bool_param(key: &str, params: &CommandParams) -> Result<Option<bool>, ()> {
    match params.get(key) {
        Some(value) => Ok(Some(value.parse::<bool>().map_err(|err|
            println_err!("Can't parse bool parameter \"{}\": err {}", key, err))?)),
        None => Ok(None)
    }
}

pub fn get_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<&'a str>, ()> {
    match params.get(name) {
        None => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) if v.is_empty() => Err(println_err!("No required \"{}\" parameter present", name)),
        Some(v) => Ok(v.split(",").collect::<Vec<&'a str>>())
    }
}

pub fn get_opt_str_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<&'a str>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<&'a str>::new()))
            } else {
                Ok(Some(v.split(",").collect::<Vec<&'a str>>()))
            },
        None => Ok(None)
    }
}

pub fn get_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<serde_json::Value, ()> {
    match params.get(name) {
        Some(v) => Ok(serde_json::from_str(v).map_err(|err|
            println_err!("Can't parse object parameter \"{}\": err {}", name, err))?),
        None => {
            println_err!("No required \"{}\" parameter present", name);
            Err(())
        }
    }
}

pub fn get_opt_object_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<serde_json::Value>, ()> {
    match params.get(name) {
        Some(_) => Ok(Some(get_object_param(name, params)?)),
        None => Ok(None)
    }
}

fn extract_array_tuples<'a>(param: &'a str) -> Vec<String> {
    let re = Regex::new(r#"\(([^\(\)]+)\),?"#).unwrap();
    re.captures_iter(param).map(|c| c[1].to_string()).collect::<Vec<String>>()
}

pub fn get_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Vec<String>, ()> {
    match params.get(name) {
        Some(v) if !v.is_empty() => {
            let tuples = extract_array_tuples(v);
            if tuples.len() == 0 {
                Err(println_err!("Parameter \"{}\" has invalid format", name))
            } else {
                Ok(tuples)
            }
        }
        _ => Err(println_err!("No required \"{}\" parameter present", name))
    }
}

pub fn get_opt_str_tuple_array_param<'a>(name: &'a str, params: &'a CommandParams) -> Result<Option<Vec<String>>, ()> {
    match params.get(name) {
        Some(v) =>
            if v.is_empty() {
                Ok(Some(Vec::<String>::new()))
            } else {
                Ok(Some(extract_array_tuples(v)))
            },
        None => Ok(None)
    }
}

pub fn ensure_active_did(ctx: &CommandContext) -> Result<String, ()> {
    match ctx.get_string_value("ACTIVE_DID") {
        Some(did) => Ok(did),
        None => Err(println_err!("There is no active did"))
    }
}

pub fn get_active_did(ctx: &CommandContext) -> Option<String> {
    ctx.get_string_value("ACTIVE_DID")
}

pub fn set_active_did(ctx: &CommandContext, did: Option<String>) {
    ctx.set_string_value("ACTIVE_DID", did.clone());
    ctx.set_sub_prompt(3, did.map(|did| format!("did({}...{})", &did[..3], &did[did.len() - 3..])));
}

pub fn ensure_opened_wallet_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("OPENED_WALLET_HANDLE") {
        Some(wallet_handle) => Ok(wallet_handle),
        None => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn ensure_opened_wallet(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened wallet now"))
    }
}

pub fn get_opened_wallet(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("OPENED_WALLET_HANDLE");
    let name = ctx.get_string_value("OPENED_WALLET_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_opened_wallet(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("OPENED_WALLET_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("OPENED_WALLET_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(2, value.map(|value| format!("wallet({})", value.1)));
}

pub fn ensure_connected_pool_handle(ctx: &CommandContext) -> Result<i32, ()> {
    match ctx.get_int_value("CONNECTED_POOL_HANDLE") {
        Some(pool_handle) => Ok(pool_handle),
        None => Err(println_err!("There is no opened pool now"))
    }
}

pub fn ensure_connected_pool(ctx: &CommandContext) -> Result<(i32, String), ()> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    match (handle, name) {
        (Some(handle), Some(name)) => Ok((handle, name)),
        _ => Err(println_err!("There is no opened pool now"))
    }
}

pub fn get_connected_pool(ctx: &CommandContext) -> Option<(i32, String)> {
    let handle = ctx.get_int_value("CONNECTED_POOL_HANDLE");
    let name = ctx.get_string_value("CONNECTED_POOL_NAME");

    if let (Some(handle), Some(name)) = (handle, name) {
        Some((handle, name))
    } else {
        None
    }
}

pub fn set_connected_pool(ctx: &CommandContext, value: Option<(i32, String)>) {
    ctx.set_int_value("CONNECTED_POOL_HANDLE", value.as_ref().map(|value| value.0.to_owned()));
    ctx.set_string_value("CONNECTED_POOL_NAME", value.as_ref().map(|value| value.1.to_owned()));
    ctx.set_sub_prompt(1, value.map(|value| format!("pool({})", value.1)));
}

#[cfg(test)]
use libindy::ledger::Ledger;

#[cfg(test)]
pub fn submit_retry<F, T, E>(ctx: &CommandContext, request: &str, parser: F) -> Result<(), ()>
    where F: Fn(&str) -> Result<T, E> {
    const SUBMIT_RETRY_CNT: usize = 3;
    const SUBMIT_TIMEOUT_SEC: u64 = 2;

    let pool_handle = ensure_connected_pool_handle(ctx).unwrap();

    for _ in 0..SUBMIT_RETRY_CNT {
        let response = Ledger::submit_request(pool_handle, request).unwrap();
        if parser(&response).is_ok() {
            return Ok(());
        }
        ::std::thread::sleep(::std::time::Duration::from_secs(SUBMIT_TIMEOUT_SEC));
    }

    return Err(());
}<|endoftext|>


<commit_before>// Lumol, an extensible molecular simulation engine
// Copyright (C) Lumol's contributors — BSD license
extern crate env_logger;
extern crate test;
extern crate walkdir;

extern crate lumol_core;
extern crate lumol_input;

use std::{env, fs, io};
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

use test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
use test::ShouldPanic::No;

use lumol_core::sys::System;
use lumol_input::{Error, Input, InteractionsInput};

fn main() {
    env_logger::init().expect("could not set logger");
    let _cleanup = TestsCleanup;

    let args: Vec<_> = env::args().collect();
    let mut opts = match test::parse_opts(&args).expect("no options") {
        Ok(opts) => opts,
        Err(msg) => panic!("{:?}", msg),
    };
    opts.verbose = true;

    let tests = all_tests();
    let result = test::run_tests_console(&opts, tests);
    match result {
        Ok(true) => {}
        Ok(false) => std::process::exit(-1),
        Err(err) => panic!("io error when running tests: {:?}", err),
    }
}

fn all_tests() -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();

    tests.extend(
        generate_tests("simulation/good", |path| {
            Box::new(move || {
                let input = Input::new(path.clone()).unwrap();
                input.read().unwrap();
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("simulation/bad", |path| {
            Box::new(move || {
                let message = get_error_message(&path);
                let result = Input::new(path.clone()).and_then(|input| input.read());

                match result {
                    Err(Error::Config(reason)) => assert_eq!(reason, message),
                    _ => panic!("This test should fail with a Config error"),
                }
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("interactions/good", |path| {
            Box::new(move || {
                let mut system = System::new();
                let input = InteractionsInput::new(path.clone()).unwrap();
                input.read(&mut system).unwrap();
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("interactions/bad", |path| {
            Box::new(move || {
                let message = get_error_message(&path);

                let mut system = System::new();
                let result =
                    InteractionsInput::new(path.clone()).and_then(|input| input.read(&mut system));

                match result {
                    Err(Error::Config(reason)) => assert_eq!(reason, message),
                    _ => panic!("This test should fail with a Config error"),
                }
            })
        }).expect("Could not generate the tests"),
    );

    return tests;
}

/// Generate the tests by calling `callback` for every TOML files at the given
/// `root`.
fn generate_tests<F>(root: &str, callback: F) -> Result<Vec<TestDescAndFn>, io::Error>
where
    F: Fn(PathBuf) -> Box<FnMut() + Send>,
{
    let mut tests = Vec::new();

    let dir = PathBuf::new().join(env!("CARGO_MANIFEST_DIR")).join("tests").join(root);
    for entry in WalkDir::new(dir) {
        let entry = try!(entry);
        let file_type = entry.file_type();
        if file_type.is_file() {
            if let Some(extension) = entry.path().extension() {
                if extension == "toml" {
                    let path = entry.path();
                    let name = String::from(root) + "/";
                    let name = name
                        + path.file_name().expect("Missing file name")
                              .to_str()
                              .expect("File name is invalid UTF-8");

                    let test = TestDescAndFn {
                        desc: TestDesc {
                            name: DynTestName(name),
                            ignore: false,
                            should_panic: No,
                        },
                        testfn: DynTestFn(callback(path.to_path_buf())),
                    };

                    tests.push(test);
                }
            }
        }
    }

    Ok(tests)
}

/// Cleanup temporary files after the tests
struct TestsCleanup;
impl Drop for TestsCleanup {
    fn drop(&mut self) {
        const REMOVE: &[&str] = &[
            "energy.dat",
            "filename.xyz",
            "cell.dat",
            "properties.dat",
            "file.log",
            "custom.dat",
            "stress.dat",
            "forces.xyz",
        ];

        for file in REMOVE {
            if let Err(err) = fs::remove_file(file) {
                match err.kind() {
                    io::ErrorKind::NotFound => {}
                    _ => panic!("io error in cleanup code: {}", err),
                }
            }
        }
    }
}

fn get_error_message(path: &Path) -> String {
    let mut buffer = String::new();
    File::open(path).and_then(|mut file| file.read_to_string(&mut buffer))
                    .expect("Could not read the input file");

    for line in buffer.lines() {
        let line = line.trim();
        if line.starts_with("#^ ") {
            return String::from(&line[3..]);
        }
    }

    panic!(
        "No error message found in {}. Please add one with the '#^ <message>' syntax.",
        path.display()
    );
}
<commit_msg>Accept a --test-threads argument for input tests<commit_after>// Lumol, an extensible molecular simulation engine
// Copyright (C) Lumol's contributors — BSD license
extern crate env_logger;
extern crate test;
extern crate walkdir;

extern crate lumol_core;
extern crate lumol_input;

use std::{env, fs, io};
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

use test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
use test::ShouldPanic::No;

use lumol_core::sys::System;
use lumol_input::{Error, Input, InteractionsInput};

fn main() {
    env_logger::init().expect("could not set logger");
    let _cleanup = TestsCleanup;

    let mut args: Vec<_> = env::args()
                              .filter(|arg| !arg.contains("test-threads"))
                              .collect();

    let mut opts = match test::parse_opts(&args).expect("no options") {
        Ok(opts) => opts,
        Err(msg) => panic!("{:?}", msg),
    };
    opts.verbose = true;

    let tests = all_tests();
    let result = test::run_tests_console(&opts, tests);
    match result {
        Ok(true) => {}
        Ok(false) => std::process::exit(-1),
        Err(err) => panic!("io error when running tests: {:?}", err),
    }
}

fn all_tests() -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();

    tests.extend(
        generate_tests("simulation/good", |path| {
            Box::new(move || {
                let input = Input::new(path.clone()).unwrap();
                input.read().unwrap();
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("simulation/bad", |path| {
            Box::new(move || {
                let message = get_error_message(&path);
                let result = Input::new(path.clone()).and_then(|input| input.read());

                match result {
                    Err(Error::Config(reason)) => assert_eq!(reason, message),
                    _ => panic!("This test should fail with a Config error"),
                }
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("interactions/good", |path| {
            Box::new(move || {
                let mut system = System::new();
                let input = InteractionsInput::new(path.clone()).unwrap();
                input.read(&mut system).unwrap();
            })
        }).expect("Could not generate the tests"),
    );

    tests.extend(
        generate_tests("interactions/bad", |path| {
            Box::new(move || {
                let message = get_error_message(&path);

                let mut system = System::new();
                let result =
                    InteractionsInput::new(path.clone()).and_then(|input| input.read(&mut system));

                match result {
                    Err(Error::Config(reason)) => assert_eq!(reason, message),
                    _ => panic!("This test should fail with a Config error"),
                }
            })
        }).expect("Could not generate the tests"),
    );

    return tests;
}

/// Generate the tests by calling `callback` for every TOML files at the given
/// `root`.
fn generate_tests<F>(root: &str, callback: F) -> Result<Vec<TestDescAndFn>, io::Error>
where
    F: Fn(PathBuf) -> Box<FnMut() + Send>,
{
    let mut tests = Vec::new();

    let dir = PathBuf::new().join(env!("CARGO_MANIFEST_DIR")).join("tests").join(root);
    for entry in WalkDir::new(dir) {
        let entry = try!(entry);
        let file_type = entry.file_type();
        if file_type.is_file() {
            if let Some(extension) = entry.path().extension() {
                if extension == "toml" {
                    let path = entry.path();
                    let name = String::from(root) + "/";
                    let name = name
                        + path.file_name().expect("Missing file name")
                              .to_str()
                              .expect("File name is invalid UTF-8");

                    let test = TestDescAndFn {
                        desc: TestDesc {
                            name: DynTestName(name),
                            ignore: false,
                            should_panic: No,
                        },
                        testfn: DynTestFn(callback(path.to_path_buf())),
                    };

                    tests.push(test);
                }
            }
        }
    }

    Ok(tests)
}

/// Cleanup temporary files after the tests
struct TestsCleanup;
impl Drop for TestsCleanup {
    fn drop(&mut self) {
        const REMOVE: &[&str] = &[
            "energy.dat",
            "filename.xyz",
            "cell.dat",
            "properties.dat",
            "file.log",
            "custom.dat",
            "stress.dat",
            "forces.xyz",
        ];

        for file in REMOVE {
            if let Err(err) = fs::remove_file(file) {
                match err.kind() {
                    io::ErrorKind::NotFound => {}
                    _ => panic!("io error in cleanup code: {}", err),
                }
            }
        }
    }
}

fn get_error_message(path: &Path) -> String {
    let mut buffer = String::new();
    File::open(path).and_then(|mut file| file.read_to_string(&mut buffer))
                    .expect("Could not read the input file");

    for line in buffer.lines() {
        let line = line.trim();
        if line.starts_with("#^ ") {
            return String::from(&line[3..]);
        }
    }

    panic!(
        "No error message found in {}. Please add one with the '#^ <message>' syntax.",
        path.display()
    );
}
<|endoftext|>