<commit_before>extern crate fomo;
extern crate tempdir;

mod utils;

use fomo::notify::*;
use std::sync::mpsc;
use tempdir::TempDir;
use std::env;
use std::path::PathBuf;
use std::sync::mpsc::Receiver;

use utils::*;

const NETWORK_PATH: &'static str = ""; // eg.: \\\\MY-PC\\Users\\MyName

#[cfg(target_os = "windows")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  recv_events(&rx)
}

#[cfg(target_os = "macos")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  let mut events = Vec::new();
  for (path, op, cookie) in inflate_events(recv_events(&rx)) {
    if op == (op::CREATE | op::WRITE) {
      events.push((path, op::WRITE, cookie));
    } else {
      events.push((path, op, cookie));
    }
  }
  events
}

#[cfg(target_os = "linux")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  let mut events = recv_events(rx);
  events.retain(|&(_, op, _)| op != op::CLOSE_WRITE);
  events
}

#[test]
fn watch_relative() {
  // both of the following tests set the same environment variable, so they must not run in
  // parallel
  {
    // watch_relative_directory
    let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
    tdir.create("dir1");

    sleep_macos(10);

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");

    sleep_windows(100);

    tdir.create("dir1/file1");

    if cfg!(target_os = "macos") {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.mkpath("dir1/file1"), op::CREATE, None) /* fsevents always
                                                                      * returns canonicalized
                                                                      * paths */ ]);
    } else {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.path().join("dir1/file1"), op::CREATE, None) ]);
    }
  }
  {
    // watch_relative_file
    let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
    tdir.create("file1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");

    sleep_windows(100);

    tdir.write("file1");

    if cfg!(target_os = "macos") {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.mkpath("file1"), op::WRITE, None) /* fsevents always returns
                                                                * canonicalized paths */ ]);
    } else {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.path().join("file1"), op::WRITE, None) ]);
    }
  }
  if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty() {
    // watch_relative_network_directory
    let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
      .expect("failed to create temporary directory");
    tdir.create("dir1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");

    sleep_windows(100);

    tdir.create("dir1/file1");

    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.path().join("dir1/file1"), op::CREATE, None) ]);
  }
  if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty() {
    // watch_relative_network_file
    let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
      .expect("failed to create temporary directory");
    tdir.create("file1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");

    sleep_windows(100);

    tdir.write("file1");

    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.path().join("file1"), op::WRITE, None) ]);
  }
}

#[test]
fn watch_absolute_directory() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("dir1");

  sleep_macos(10);

  let watch_path = tdir.path().join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  if cfg!(target_os = "macos") {
    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.mkpath("dir1/file1"), op::CREATE, None) /* fsevents always
                                                                    * returns canonicalized
                                                                    * paths */ ]);
  } else {
    assert_eq!(recv_events_simple(&rx),
               vec![ (watch_path.join("file1"), op::CREATE, None) ]);
  }
}

#[test]
fn watch_absolute_file() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  if cfg!(target_os = "macos") {
    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.mkpath("file1"), op::WRITE, None) /* fsevents always returns
                                                              * canonicalized paths */ ]);
  } else {
    assert_eq!(recv_events_simple(&rx),
               vec![ (watch_path, op::WRITE, None) ]);
  }
}

#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_directory() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("dir1");

  let watch_path = tdir.path().join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_file() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}

#[test]
fn watch_canonicalized_directory() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("dir1");

  sleep_macos(10);

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
fn watch_canonicalized_file() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_canonicalized_network_directory() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("dir1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_canonicalized_network_file() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}
<commit_msg>Attempt to fix another flaky mac test.<commit_after>extern crate fomo;
extern crate tempdir;

mod utils;

use fomo::notify::*;
use std::sync::mpsc;
use tempdir::TempDir;
use std::env;
use std::path::PathBuf;
use std::sync::mpsc::Receiver;

use utils::*;

const NETWORK_PATH: &'static str = ""; // eg.: \\\\MY-PC\\Users\\MyName

#[cfg(target_os = "windows")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  recv_events(&rx)
}

#[cfg(target_os = "macos")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  let mut events = Vec::new();
  for (path, op, cookie) in inflate_events(recv_events(&rx)) {
    if op == (op::CREATE | op::WRITE) {
      events.push((path, op::WRITE, cookie));
    } else {
      events.push((path, op, cookie));
    }
  }
  events
}

#[cfg(target_os = "linux")]
fn recv_events_simple(rx: &Receiver<RawEvent>) -> Vec<(PathBuf, Op, Option<u32>)> {
  let mut events = recv_events(rx);
  events.retain(|&(_, op, _)| op != op::CLOSE_WRITE);
  events
}

#[test]
fn watch_relative() {
  // both of the following tests set the same environment variable, so they must not run in
  // parallel
  {
    // watch_relative_directory
    let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
    tdir.create("dir1");

    sleep_macos(10);

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");

    sleep_windows(100);

    tdir.create("dir1/file1");

    if cfg!(target_os = "macos") {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.mkpath("dir1/file1"), op::CREATE, None) /* fsevents always
                                                                      * returns canonicalized
                                                                      * paths */ ]);
    } else {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.path().join("dir1/file1"), op::CREATE, None) ]);
    }
  }
  {
    // watch_relative_file
    let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
    tdir.create("file1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");

    sleep_windows(100);

    tdir.write("file1");

    if cfg!(target_os = "macos") {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.mkpath("file1"), op::WRITE, None) /* fsevents always returns
                                                                * canonicalized paths */ ]);
    } else {
      assert_eq!(recv_events_simple(&rx),
                 vec![ (tdir.path().join("file1"), op::WRITE, None) ]);
    }
  }
  if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty() {
    // watch_relative_network_directory
    let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
      .expect("failed to create temporary directory");
    tdir.create("dir1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");

    sleep_windows(100);

    tdir.create("dir1/file1");

    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.path().join("dir1/file1"), op::CREATE, None) ]);
  }
  if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty() {
    // watch_relative_network_file
    let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
      .expect("failed to create temporary directory");
    tdir.create("file1");

    env::set_current_dir(tdir.path()).expect("failed to change working directory");

    let (tx, rx) = mpsc::channel();
    let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
      .expect("failed to create recommended watcher");
    watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");

    sleep_windows(100);

    tdir.write("file1");

    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.path().join("file1"), op::WRITE, None) ]);
  }
}

#[test]
fn watch_absolute_directory() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("dir1");

  sleep_macos(10);

  let watch_path = tdir.path().join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);
  sleep_macos(100);

  tdir.create("dir1/file1");

  sleep_macos(100);

  if cfg!(target_os = "macos") {
    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.mkpath("dir1/file1"), op::CREATE, None) /* fsevents always
                                                                    * returns canonicalized
                                                                    * paths */ ]);
  } else {
    assert_eq!(recv_events_simple(&rx),
               vec![ (watch_path.join("file1"), op::CREATE, None) ]);
  }
}

#[test]
fn watch_absolute_file() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  if cfg!(target_os = "macos") {
    assert_eq!(recv_events_simple(&rx),
               vec![ (tdir.mkpath("file1"), op::WRITE, None) /* fsevents always returns
                                                              * canonicalized paths */ ]);
  } else {
    assert_eq!(recv_events_simple(&rx),
               vec![ (watch_path, op::WRITE, None) ]);
  }
}

#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_directory() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("dir1");

  let watch_path = tdir.path().join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_file() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}

#[test]
fn watch_canonicalized_directory() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("dir1");

  sleep_macos(10);

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
fn watch_canonicalized_file() {
  let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_canonicalized_network_directory() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("dir1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("dir1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.create("dir1/file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path.join("file1"), op::CREATE, None) ]);
}

#[test]
#[cfg(target_os = "windows")]
fn watch_canonicalized_network_file() {
  if NETWORK_PATH.is_empty() {
    return;
  }

  let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir")
    .expect("failed to create temporary directory");
  tdir.create("file1");

  let watch_path = tdir.path().canonicalize().expect("failed to canonicalize path").join("file1");
  let (tx, rx) = mpsc::channel();
  let mut watcher: RecommendedWatcher = Watcher::new_raw(tx)
    .expect("failed to create recommended watcher");
  watcher.watch(&watch_path, RecursiveMode::Recursive).expect("failed to watch directory");

  sleep_windows(100);

  tdir.write("file1");

  assert_eq!(recv_events_simple(&rx),
             vec![ (watch_path, op::WRITE, None) ]);
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! view_tests {
    ($tree_macro:ident) => (
        use ::entmut::Nav;

        #[test]
        #[allow(unused_variables)]
        fn view_instantiation() {
            let t = $tree_macro!["a"];
            let v = t.view();
        }

        #[test]
        fn view_preserves_leaf_topology() {
            let t = $tree_macro!["a"];
            let v = t.view();
            assert![v.at_leaf()];
            assert![v.at_root()];
            assert_eq![0, v.child_count()];
        }

        #[test]
        fn view_preserves_leaf_data() {
            let t = $tree_macro!["a"];
            let v = t.view();
            assert_eq!["a", *v];
        }

        #[test]
        fn view_seek_root_sibling_noop_succeeds() {
            let t = $tree_macro!["a"];
            let mut v = t.view();
            assert![v.seek_sibling(0)];
        }

        #[test]
        fn view_seek_root_sibling_fails() {
            let t = $tree_macro!["a"];
            let mut v = t.view();
            assert![! v.seek_sibling(-1)];
            assert![! v.seek_sibling(1)];
        }

        #[test]
        fn view_counts_children_correctly() {
            let t = $tree_macro!["a", ["b", ["e"], ["f"]], ["c"], ["d"]];
            let mut v = t.view();
            assert_eq![3, v.child_count()];
            assert![v.seek_child(0)];
            assert_eq![2, v.child_count()];
            assert![v.seek_sibling(1)];
            assert_eq![0, v.child_count()];
        }
        );
}
<commit_msg>A few more tests for impls of the Nav trait.<commit_after>#[macro_export]
macro_rules! view_tests {
    ($tree_macro:ident) => (
        use ::entmut::Nav;
        use std::collections::HashMap;
        use std::hash::Hash;
        use std::iter::Iterator;
        use std::ops::Deref;

        #[test]
        #[allow(unused_variables)]
        fn view_instantiation() {
            let t = $tree_macro!["a"];
            let v = t.view();
        }

        #[test]
        fn view_preserves_leaf_topology() {
            let t = $tree_macro!["a"];
            let v = t.view();
            assert![v.at_leaf()];
            assert![v.at_root()];
            assert_eq![0, v.child_count()];
        }

        #[test]
        fn view_preserves_leaf_data() {
            let t = $tree_macro!["a"];
            let v = t.view();
            assert_eq!["a", *v];
        }

        #[test]
        fn view_seek_root_sibling_noop_succeeds() {
            let t = $tree_macro!["a"];
            let mut v = t.view();
            assert![v.seek_sibling(0)];
        }

        #[test]
        fn view_seek_root_sibling_fails() {
            let t = $tree_macro!["a"];
            let mut v = t.view();
            assert![! v.seek_sibling(-1)];
            assert![! v.seek_sibling(1)];
        }

        #[test]
        fn view_counts_children_correctly() {
            let t = $tree_macro!["a", ["b", ["e"], ["f"]], ["c"], ["d"]];
            let mut v = t.view();
            assert_eq![3, v.child_count()];
            assert![v.seek_child(0)];
            assert_eq![2, v.child_count()];
            assert![v.seek_sibling(1)];
            assert_eq![0, v.child_count()];
        }

        #[derive(Debug, Clone, Copy, Eq, PartialEq)]
        enum TraversalState {
            Visited,
            Exhausted,
        }

        // Traversal of `nav`, which should have unique data at each node.
        //
        // When starting from the tree root, traversal order is: parent before
        // child, left sibling before right.
        //
        // When starting from elsewhere, traversal order is: traverse subtree
        // rooted at initial position as though it were rooted there, then
        // recursively move upwards towards the root and traverse each subtree
        // of unvisited nodes as though rooted there.
        //
        // Returns the next data item in the traversal, or None if the tree has
        // been exhausted.
        fn traverse_next<T, N>(nav: &mut N, state: &mut HashMap<T, TraversalState>) -> Option<T>
            where T: Copy + Eq + PartialEq + Hash,  N: Nav + Deref<Target=T> {
                loop {
                    let data = **nav;
                    match state.get(&data).map(|x| *x)  {
                        None => {
                            // Haven't visited this node before. Mark as visited
                            // and return.
                            state.insert(data, TraversalState::Visited);
                            return Some(data)
                        },
                        Some(TraversalState::Exhausted) => {
                            // Visited this node and all children. Move to next
                            // sibling.
                            if nav.seek_sibling(1) {
                                continue
                            }
                            // No more siblings. Move to parent.
                            if nav.to_parent() {
                                continue
                            }
                            // No parent. Must be at root. Terminate.
                            return None
                        },
                        Some(TraversalState::Visited) => {
                            if nav.at_leaf() {
                                // No children. Mark node as exhausted.
                                state.insert(data, TraversalState::Exhausted);
                                continue
                            } else {
                                // Last child has been visited. Mark node as exhausted.
                                let last_child_index = nav.child_count() - 1;
                                if nav.seek_child(last_child_index) && state.contains_key(&**nav) {
                                    assert![nav.to_parent()];
                                    state.insert(data, TraversalState::Exhausted);
                                    continue
                                }
                                assert![nav.to_parent()];
                                // Node has been visited but is not exhausted. Move
                                // to first child.
                                if nav.seek_child(0) {
                                    continue
                                }
                                assert![false];
                            }
                        },
                    }
                }
            }

        // Iterator wrapping traversal_next.
        struct NavIter<N, T> where T: Copy + Eq + PartialEq + Hash,  N: Nav + Deref<Target=T> {
            nav: N,
            state: HashMap<T, TraversalState>,
        }

        impl<N, T> NavIter<N, T>
            where T: Copy + Eq + PartialEq + Hash, N: Nav + Deref<Target=T> {
                fn new(nav: N) -> Self { NavIter { nav: nav, state: HashMap::new(), } }
            }

        impl<N, T> Iterator for NavIter<N, T>
            where T: Copy + Eq + PartialEq + Hash, N: Nav + Deref<Target=T> {
                type Item = T;

                fn next(&mut self) -> Option<T> {
                    traverse_next(&mut self.nav, &mut self.state)
                }
            }

        // Consumes `nav` and iterates through the entire tree in the traversal
        // order defined by `traversal_next`.
        fn traversal_seq<N, T>(nav: N) -> Vec<T>
            where T: Copy + Eq + PartialEq + Hash, N: Nav + Deref<Target=T> {
                NavIter::new(nav).collect()
            }

        #[test]
        fn view_traversal_maintains_tree_order() {
            {
                let t = $tree_macro![1, [2], [3]];
                assert_eq![traversal_seq(t.view()), vec![1, 2, 3]];
            }
            {
                let t = $tree_macro![1, [2, [3]], [4]];
                assert_eq![traversal_seq(t.view()), vec![1, 2, 3, 4]];
            }
            {
                let t = $tree_macro![1, [2, [3, [4]], [5], [6]], [7]];
                assert_eq![traversal_seq(t.view()), vec![1, 2, 3, 4, 5, 6, 7]];
            }
            {
                let t = $tree_macro![1, [2], [3, [4]], [5]];
                assert_eq![traversal_seq(t.view()), vec![1, 2, 3, 4, 5]];
            }
        }

        #[test]
        fn view_nonroot_seek_sibling_noop_succeeds() {
            let t = $tree_macro![1, [2], [3]];
            let mut nav = t.view();
            assert![nav.seek_child(0)];
            assert![nav.seek_sibling(0)];
            assert_eq![traversal_seq(nav), vec![2, 3, 1]];
        }

        #[test]
        fn view_to_root_seeks_root() {
            {
                let t = $tree_macro![1];
                let mut nav = t.view();
                nav.to_root();
                assert_eq![traversal_seq(nav), vec![1]];
            }
            {
                let t = $tree_macro![1, [2], [3], [4]];
                let mut nav = t.view();
                for i in 0..3 {
                    nav.seek_child(i);
                    assert_eq![*nav, i + 2];
                    nav.to_root();
                    assert_eq![traversal_seq(nav.clone()), vec![1, 2, 3, 4]];
                }
            }
            {
                let t = $tree_macro![1, [2], [3], [4, [5], [6, [7]]]];
                let mut nav = t.view();
                assert![nav.seek_child(2)];
                assert![nav.seek_child(1)];
                assert_eq![*nav, 6];
                nav.to_root();
                assert_eq![traversal_seq(nav), vec![1, 2, 3, 4, 5, 6, 7]];
            }
        }

        // TODO: test that seeking invalid child indices returns false.

        // TODO: test seek_first_sibling and seek_last_sibling behaviors.

        // TODO: test at_leaf, at_root in complex trees after arbitrary
        // navigation operations.
        );
}
<|endoftext|>


<commit_before>use std::rand::random;
use std::os;
use std::io::File;

fn main() {
    let args: ~[~str] = os::args();
    if args.len() != 2 {
        println!("Usage: {:s} <inputfile>", args[0]);
    } else {
        let fname = args[1];
        let path = Path::new(fname.clone());
        let msg_file = File::open(&path);

        match (msg_file) {
            Some(mut msg) => {
                let msg_bytes: ~[u8] = msg.read_to_end();
                let share1_file
                       = File::create(&Path::new(fname + ".share1"));
                let share2_file
                       = File::create(&Path::new(fname + ".share2"));

                match (share1_file, share2_file) {
                    (Some(share1), Some(share2)) => {
                        split(msg_bytes, share1, share2);
                        } ,
                    (_, _) => fail!("Error opening output files!"),
                }
            } ,
            None => fail!("Error opening message file: {:s}", fname)
        }
    }
}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}

fn split(msg_bytes: &[u8], mut share1: File, mut share2: File) {
    let mut random_bytes: ~[u8] = ~[];
    // This is not cryptographically strong randomness!
    // (For entertainment purposes only.)
    for _ in range(0, msg_bytes.len()) {
	let random_byte = random();
	random_bytes.push(random_byte);
    }

    let encrypted_bytes = xor(msg_bytes, random_bytes);
    share1.write(random_bytes);
    share2.write(encrypted_bytes);
}
<commit_msg>Finish first attempt at joiner<commit_after>use std::rand::random;
use std::os;
use std::io::File;

fn main() {
    let args: ~[~str] = os::args();
    if args.len() != 3 {
        println!("Usage: {:s} <splitFile1> <splitFile2>", args[0]);
    } else {
        let f1name = args[1];
        let f2name = args[2];
        let path1 = Path::new(f1name.clone());
        let path2 = Path::new(f2name.clone());
        let msg_file1 = File::open(&path1);
        let msg_file2 = File::open(&path2);

        match (msg_file1, msg_file2) {
            Some(mut msg1, mut msg2) => {
                let msg1_bytes: ~[u8] = msg1.read_to_end();
                let msg2_bytes: ~[u8] = msg2.read_to_end();
                let output_file
                       = File::create(&Path::new("originalMsg"));

                match (output_file) {
                    (Some(output)) => {
                        split(msg1_bytes, msg2_bytes, output_file);
                        } ,
                    (_, _) => fail!("Error opening output files!"),
                }
            } ,
            None => fail!("Error opening message file: {:s}", fname)
        }
    }
}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
	ret.push(a[i] ^ b[i]);
    }
    ret
}

fn split(msg1_bytes: &[u8], mut msg2_bytes: &[u8], mut output_file: File) {
    let mut original_bytes: ~[u8] = xor(msg1_bytes, msg2_bytes);
    output_file.write(original_bytes);
}
<|endoftext|>


<commit_before>use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;
use errors::anoncreds::AnoncredsError;

pub struct AnoncredsAPI {
    command_executor: Arc<CommandExecutor>,
}

impl AnoncredsAPI {
    pub fn new(command_executor: Arc<CommandExecutor>) -> AnoncredsAPI {
        AnoncredsAPI { command_executor: command_executor }
    }

    /// Creates master secret key for prover.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Master secret key as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_master_secret(cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates public/private keys pair for issuer.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of
    /// (Public primary key, Secret Key, Public non-revocation key, Secret non-revocation key)
    /// as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_key_pair(schema: &[&u8],
                       cb: Box<Fn(
                           Result<((String, String, String, String)), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    pub fn create_context_attribute(i_a: String, user_id: String,
                                    cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {

    }

    /// Issues accumulator.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// accumulator_id: accumulator id as a byte array.
    /// max_claims: maximum number of claims within accumulator as a byte array.
    /// public_key_non_revocation: non-revocation public key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of (Accumulator, Tails, Accumulator public key, Accumulator secret key) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_accumulator(schema: &[&u8], accumulator_id: &[&u8], max_claims: &[&u8],
                             public_key_non_revocation: &[&u8],
                             cb: Box<Fn(
                                 Result<((String, String, String, String)),
                                     AnoncredsError>
                             ) + Send>) {
        unimplemented!();
    }

    pub fn issue_claim(attributes: String, accumulator: String,i_a: String, i: String,
                       claim_request: String, context_attribute: String, public_key: String,
                       secret_key: String, public_key_revocation: String,
                       secret_key_revocation: String, tails: String,
                       secret_key_accumulator: String,
                       cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {

    }

    /// Creates claim request.
    ///
    /// #Params
    /// master_secret: prover master secret as a byte array.
    /// public_key: issuer public_key as a byte array.
    /// public_key_non_revocation: issuer non-revocation public key as a byte array.
    /// request_non_revocation: whether to request non-revocation claim as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Claim request as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_claim_request(master_secret: &[&u8], public_key: &[&u8],
                                public_key_non_revocation: &[&u8], request_non_revocation: &[&u8],
                                cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    pub fn create_proof(proof_input: String, nonce: String, claims: String,
                        public_key_revocation: String, accum: String, public_key: String,
                        master_secret: String,
                        cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {

    }

    pub fn verify_proof(proof_input: String, proof: String, revealed_attributes: String,
                        nonce: String, public_key_revocation: String,
                        public_key_accumulator: String, accumulator: String,
                        public_key: String, attributes: String,
                        cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {

    }
}

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

    #[test]
    fn anoncreds_api_can_be_created() {
        let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        assert! (true, "No crashes on AnoncredsAPI::new");
    }

    #[test]
    fn anoncredsn_api_can_be_dropped() {
        fn drop_test() {
            let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        }

        drop_test();
        assert! (true, "No crashes on AnoncredsAPI::drop");
    }
}<commit_msg>Added documentation<commit_after>use commands::{Command, CommandExecutor};
use std::error;
use std::sync::Arc;
use errors::anoncreds::AnoncredsError;

pub struct AnoncredsAPI {
    command_executor: Arc<CommandExecutor>,
}

impl AnoncredsAPI {
    pub fn new(command_executor: Arc<CommandExecutor>) -> AnoncredsAPI {
        AnoncredsAPI { command_executor: command_executor }
    }

    /// Creates master secret key for prover.
    ///
    /// #Params
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Master secret key as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_master_secret(cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates public/private keys pair for issuer.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of
    /// (Public primary key, Secret Key, Public non-revocation key, Secret non-revocation key)
    /// as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_key_pair(schema: &[&u8],
                       cb: Box<Fn(
                           Result<((String, String, String, String)), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    pub fn create_context_attribute(i_a: String, user_id: String,
                                    cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {

    }

    /// Issues accumulator.
    ///
    /// #Params
    /// schema: claim definition schema as a byte array.
    /// accumulator_id: accumulator id as a byte array.
    /// max_claims: maximum number of claims within accumulator as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Tuple of (Accumulator, Tails, Accumulator public key, Accumulator secret key) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn issue_accumulator(schema: &[&u8], accumulator_id: &[&u8], max_claims: &[&u8],
                             public_key_non_revocation: &[&u8],
                             cb: Box<Fn(
                                 Result<((String, String, String, String)),
                                     AnoncredsError>
                             ) + Send>) {
        unimplemented!();
    }

    pub fn issue_claim(attributes: String, accumulator: String,i_a: String, i: String,
                       claim_request: String, context_attribute: String, public_key: String,
                       secret_key: String, public_key_revocation: String,
                       secret_key_revocation: String, tails: String,
                       secret_key_accumulator: String,
                       cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {

    }

    /// Creates claim request.
    ///
    /// #Params
    /// master_secret: prover's master secret as a byte array.
    /// public_key: issuer's public_key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// request_non_revocation: whether to request non-revocation claim as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Claim request as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_claim_request(master_secret: &[&u8], public_key: &[&u8],
                                public_key_non_revocation: &[&u8], request_non_revocation: &[&u8],
                                cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    /// Creates proof.
    ///
    /// #Params
    /// proof_input: description of a proof to be presented
    ///     (revealed attributes, predicates, timestamps for non-revocation) as a byte array.
    /// nonce: verifier's nonce as a byte array.
    /// claims: necessary claims for proof as a byte array.
    /// master_secret: prover's master secret key as a byte array.
    /// public_key: issuer's public key as a byte array.
    /// public_key_non_revocation: issuer's non-revocation public key as a byte array.
    /// accumulator: accumulator as a byte array.
    /// cb: Callback that takes command result as a parameter.
    ///
    /// #Returns
    /// Typle of (
    ///         Proof (both primary and non-revocation),
    ///         Revealed attributes (initial non-encoded values)
    ///     ) as a String.
    ///
    /// #Errors
    /// No method specific errors.
    /// See `AnoncredsError` docs for common errors description.
    pub fn create_proof(proof_input: &[&u8], nonce: &[&u8], claims: &[&u8],
                        public_key_non_revocation: &[&u8], accumulator: &[&u8], public_key: &[&u8],
                        master_secret: &[&u8],
                        cb: Box<Fn(Result<(String, String), AnoncredsError>) + Send>) {
        unimplemented!();
    }

    pub fn verify_proof(proof_input: String, proof: String, revealed_attributes: String,
                        nonce: String, public_key_revocation: String,
                        public_key_accumulator: String, accumulator: String,
                        public_key: String, attributes: String,
                        cb: Box<Fn(Result<(String), AnoncredsError>) + Send>) {

    }

    pub fn create_nonce() {

    }
}

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

    #[test]
    fn anoncreds_api_can_be_created() {
        let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        assert! (true, "No crashes on AnoncredsAPI::new");
    }

    #[test]
    fn anoncredsn_api_can_be_dropped() {
        fn drop_test() {
            let anoncreds_api = AnoncredsAPI::new(Arc::new(CommandExecutor::new()));
        }

        drop_test();
        assert! (true, "No crashes on AnoncredsAPI::drop");
    }
}<|endoftext|>


<commit_before>use gmp::mpq::Mpq;
use gmp::mpz::Mpz;
use std::borrow::Borrow;
use std::collections::hash_map::{Entry, HashMap};
use std::collections::HashSet;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader, Read, stdin};
use std::result::Result;
use std::str::FromStr;

pub struct BallotParser {
    pub candidates: Vec<String>,
    pub candidate_index: HashMap<String, usize>,
    pub ballots: Vec<(Box<[Box<[usize]>]>, Mpq)>,
}

fn parse_rational(s: &str) -> Result<Mpq, ()> {
    match s.find('/') {
        Some(i) => Ok(Mpq::ratio(&Mpz::from_str(&s[..i])?, &Mpz::from_str(&s[i + 1..])?)),
        None => Ok(Mpq::ratio(&Mpz::from_str(s)?, &Mpz::one())),
    }
}

impl BallotParser {
    fn new() -> BallotParser {
        BallotParser {
            candidates: Vec::new(),
            candidate_index: HashMap::new(),
            ballots: Vec::new(),
        }
    }

    fn parse_candidate(&mut self, name: &str, used: &mut HashSet<usize>) -> Result<usize, String> {
        let name = name.trim();
        if name.is_empty() {
            Err("empty candidate name")?
        }
        let n = match self.candidate_index.entry(name.to_string()) {
            Entry::Occupied(e) => *e.get(),
            Entry::Vacant(e) => {
                let n = self.candidates.len();
                e.insert(n);
                self.candidates.push(name.to_string());
                n
            }
        };
        if used.insert(n) {
            Ok(n)
        } else {
            Err(format!("candidate repeated: {}", name))
        }
    }

    fn parse_group(&mut self,
                   group: &str,
                   used: &mut HashSet<usize>)
                   -> Result<Box<[usize]>, String> {
        Ok(group.split('=')
            .map(|name| self.parse_candidate(name, used))
            .collect::<Result<Vec<_>, _>>()?
            .into_boxed_slice())
    }

    fn parse_groups(&mut self,
                    groups: &str,
                    used: &mut HashSet<usize>)
                    -> Result<Box<[Box<[usize]>]>, String> {
        Ok(groups.split('>')
            .map(|group| self.parse_group(group, used))
            .collect::<Result<Vec<_>, _>>()?
            .into_boxed_slice())
    }

    fn add_ballot(&mut self, line: &str) -> Result<(), String> {
        let line = line.trim();
        if line.is_empty() {
            return Ok(());
        }

        let (w, groups) = match line.find(':') {
            Some(i) => {
                let w = parse_rational(&line[..i]).map_err(|()| "cannot parse ballot weight")?;
                if w <= Mpq::zero() {
                    Err("non-positive ballot weight")?
                }
                (w, &line[i + 1..])
            }
            None => (Mpq::one(), &line[..]),
        };

        let ballot = (self.parse_groups(groups, &mut HashSet::new())?, w);
        self.ballots.push(ballot);
        Ok(())
    }

    fn add_ballots<R: Read>(&mut self, buf: BufReader<R>) -> Result<(), (usize, String)> {
        for (lineno, line) in buf.lines().enumerate() {
            self.add_ballot(&line.map_err(|e| (lineno, String::from(e.description())))?)
                .map_err(|e| (lineno, e))?;
        }
        Ok(())
    }

    fn add_ballot_file(&mut self, filename: &str) -> Result<(), String> {
        let file: Box<Read> = if filename == "-" {
            Box::new(stdin())
        } else {
            Box::new(File::open(filename).map_err(|e| format!("error: {}: {}", filename, e))?)
        };
        self.add_ballots(BufReader::new(file))
            .map_err(|(lineno, e)| format!("{}:{}: error: {}", filename, lineno + 1, e))
    }
}

pub fn parse_ballot_files<Str>(filenames: &[Str]) -> Result<BallotParser, String>
    where Str: Borrow<str>
{
    let mut bp = BallotParser::new();
    for filename in filenames.iter() {
        bp.add_ballot_file(filename.borrow())?;
    }
    Ok(bp)
}
<commit_msg>String::from(e.description()) ↦ e.to_string()<commit_after>use gmp::mpq::Mpq;
use gmp::mpz::Mpz;
use std::borrow::Borrow;
use std::collections::hash_map::{Entry, HashMap};
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufRead, BufReader, Read, stdin};
use std::result::Result;
use std::str::FromStr;

pub struct BallotParser {
    pub candidates: Vec<String>,
    pub candidate_index: HashMap<String, usize>,
    pub ballots: Vec<(Box<[Box<[usize]>]>, Mpq)>,
}

fn parse_rational(s: &str) -> Result<Mpq, ()> {
    match s.find('/') {
        Some(i) => Ok(Mpq::ratio(&Mpz::from_str(&s[..i])?, &Mpz::from_str(&s[i + 1..])?)),
        None => Ok(Mpq::ratio(&Mpz::from_str(s)?, &Mpz::one())),
    }
}

impl BallotParser {
    fn new() -> BallotParser {
        BallotParser {
            candidates: Vec::new(),
            candidate_index: HashMap::new(),
            ballots: Vec::new(),
        }
    }

    fn parse_candidate(&mut self, name: &str, used: &mut HashSet<usize>) -> Result<usize, String> {
        let name = name.trim();
        if name.is_empty() {
            Err("empty candidate name")?
        }
        let n = match self.candidate_index.entry(name.to_string()) {
            Entry::Occupied(e) => *e.get(),
            Entry::Vacant(e) => {
                let n = self.candidates.len();
                e.insert(n);
                self.candidates.push(name.to_string());
                n
            }
        };
        if used.insert(n) {
            Ok(n)
        } else {
            Err(format!("candidate repeated: {}", name))
        }
    }

    fn parse_group(&mut self,
                   group: &str,
                   used: &mut HashSet<usize>)
                   -> Result<Box<[usize]>, String> {
        Ok(group.split('=')
            .map(|name| self.parse_candidate(name, used))
            .collect::<Result<Vec<_>, _>>()?
            .into_boxed_slice())
    }

    fn parse_groups(&mut self,
                    groups: &str,
                    used: &mut HashSet<usize>)
                    -> Result<Box<[Box<[usize]>]>, String> {
        Ok(groups.split('>')
            .map(|group| self.parse_group(group, used))
            .collect::<Result<Vec<_>, _>>()?
            .into_boxed_slice())
    }

    fn add_ballot(&mut self, line: &str) -> Result<(), String> {
        let line = line.trim();
        if line.is_empty() {
            return Ok(());
        }

        let (w, groups) = match line.find(':') {
            Some(i) => {
                let w = parse_rational(&line[..i]).map_err(|()| "cannot parse ballot weight")?;
                if w <= Mpq::zero() {
                    Err("non-positive ballot weight")?
                }
                (w, &line[i + 1..])
            }
            None => (Mpq::one(), &line[..]),
        };

        let ballot = (self.parse_groups(groups, &mut HashSet::new())?, w);
        self.ballots.push(ballot);
        Ok(())
    }

    fn add_ballots<R: Read>(&mut self, buf: BufReader<R>) -> Result<(), (usize, String)> {
        for (lineno, line) in buf.lines().enumerate() {
            self.add_ballot(&line.map_err(|e| (lineno, e.to_string()))?)
                .map_err(|e| (lineno, e))?;
        }
        Ok(())
    }

    fn add_ballot_file(&mut self, filename: &str) -> Result<(), String> {
        let file: Box<Read> = if filename == "-" {
            Box::new(stdin())
        } else {
            Box::new(File::open(filename).map_err(|e| format!("error: {}: {}", filename, e))?)
        };
        self.add_ballots(BufReader::new(file))
            .map_err(|(lineno, e)| format!("{}:{}: error: {}", filename, lineno + 1, e))
    }
}

pub fn parse_ballot_files<Str>(filenames: &[Str]) -> Result<BallotParser, String>
    where Str: Borrow<str>
{
    let mut bp = BallotParser::new();
    for filename in filenames.iter() {
        bp.add_ballot_file(filename.borrow())?;
    }
    Ok(bp)
}
<|endoftext|>


<commit_before>#![feature(phase)]

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

use std::borrow::ToOwned;

use baps3_protocol::client::{Client, Request, Response};
use baps3_protocol::proto::{Unpacker, Message};

fn commands() {
    println!("Commands: ");
    println!("  !c HOST:PORT - connect (if not connected)");
    println!("  !d           - disconnect (if connected)");
    println!("  !h           - this help message");
    println!("  !t           - report current time");
    println!("  !T           - toggle whether to report time");
    println!("  !q           - quit");
    println!("");
    println!("Anything not prefixed with ! is sent to the server.");
}

fn main() {
    let (int_request_tx, int_request_rx) = channel();

    std::thread::Thread::spawn(move || { stdin_loop(int_request_tx)})
                        .detach();

    println!("Currently disconnected.");
    println!("Type !h <newline> for command help");

    'l: for msg in int_request_rx.iter() {
        match msg {
            Request::Quit => break,
            Request::SendMessage(msg) => match msg.as_str_vec().as_slice() {
                ["!c", dest] => match Client::new(dest) {
                    Ok(client) => {
                        let quit = client_main_loop(
                            client,
                            &int_request_rx,
                        );
                        println!("Disconnected");

                        if quit { break 'l };
                    },
                    Err(e) => println!("{}", e)
                },
                ["!h"] => commands(),
                ["!q"] => return,
                _ => println!("can't do that, disconnected!")
            }
        }
    }

    println!("Quitting");
}

fn stdin_loop(
    request_tx: Sender<Request>
) {
    let mut u = Unpacker::new();

    for line in std::io::stdin().lock().lines() {
        match line {
            Ok(l) => send_message(&request_tx, &mut u, l.as_slice()),
            Err(e) => {
                println!("{}", e);
                return;
            }
        }
    }

    request_tx.send(Request::Quit);
}

fn send_message(
    request_tx: &Sender<Request>,
    unpacker: &mut Unpacker,
    message: &str
) {
    for pline in unpacker.feed(message.as_slice()).iter() {
        if let [ref cmd, args..] = pline.as_slice() {
            request_tx.send(Request::SendMessage(Message::new(cmd, args)));
        }
    }
}

fn forward(tx: Sender<Request>, word: &str, args: &[&str]) {
    println!("> {} {}", word, args);
    tx.send(Request::SendMessage(Message::new(word, args)));
}

struct CliClient {
    /// The last time-stamp reported by the server.
    last_time: String,

    /// Whether to report time.
    report_time: bool
}
impl CliClient {
    /// Creates a new CliClient.
    fn new() -> CliClient {
        CliClient { last_time:   "0:00".to_owned(),
                    report_time: true }
    }

    /// Toggles whether to report time.
    fn toggle_time(&mut self) {
        self.report_time = !self.report_time;
        println!("i time reporting: {}",
                 if self.report_time { "on" } else { "off" });
    }

    /// Reports the current time.
    fn report_time(&self) {
        println!("T {}", self.last_time);
    }

    /// Handles a TIME notification for this CliClient.
    fn time(&mut self, t: &str) {
        if let Some(ti) = t.parse::<i64>() {
            let d = std::time::Duration::microseconds(ti);
            let s = format!("{}{:02}:{:02}",
                if 0 < d.num_hours() { format!("{}:", d.num_hours()) }
                else                 { String::new()                 },
                d.num_minutes() % 60,
                d.num_seconds() % 60);
            if s != self.last_time {
                self.last_time = s;
                if self.report_time { self.report_time() };
            }
        }
    }
}

/// Returns true if the outer main loop must exit.
fn client_main_loop(Client {
    request_tx,
    response_rx
}: Client, int_request_rx: &Receiver<Request>) -> bool {
    let mut state = CliClient::new();

    let sel = std::comm::Select::new();

    let mut reqh = sel.handle(int_request_rx);
    unsafe { reqh.add(); }

    let mut resh = sel.handle(&response_rx);
    unsafe { resh.add(); }

    loop {
        let id = sel.wait();
        if id == reqh.id() {
            match reqh.recv_opt() {
                Ok(Request::SendMessage(msg)) =>
                  match msg.as_str_vec().as_slice() {
                    ["!d"] => {
                        request_tx.send(Request::Quit);
                        return false;
                    },
                    ["!h"] => commands(),
                    ["!q"] => {
                        request_tx.send(Request::Quit);
                        return true;
                    }
                    ["!T"] => state.toggle_time(),
                    ["!t"] => state.report_time(),
                    [word, args..] => forward(request_tx.clone(), word, args),
                    [] => ()
                },
                Ok(req) => request_tx.send(req),
                Err(_) => return false
            }
        } else {
            match resh.recv_opt() {
                Ok(Response::Gone) => return false,
                Ok(Response::ClientError(e)) => {
                    println!("! {}", e);
                    return false;
                },
                Ok(Response::Message(m)) => match &*m.as_str_vec() {
                    [ "TIME", t ] => state.time(t),
                    [ word, args.. ] => println!("< {} {}", word, args),
                    [] => ()
                },
                Err(_) => {
                    return false;
                }
            }
        }
    }
}
<commit_msg>More CLI refactoring.<commit_after>#![feature(phase)]

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

use std::borrow::ToOwned;

use baps3_protocol::client::{Client, Request, Response};
use baps3_protocol::proto::{Unpacker, Message};

fn commands() {
    println!("Commands: ");
    println!("  !c HOST:PORT - connect (if not connected)");
    println!("  !d           - disconnect (if connected)");
    println!("  !h           - this help message");
    println!("  !t           - report current time");
    println!("  !T           - toggle whether to report time");
    println!("  !q           - quit");
    println!("");
    println!("Anything not prefixed with ! is sent to the server.");
}

fn main() {
    let (int_request_tx, int_request_rx) = channel();

    std::thread::Thread::spawn(move || { stdin_loop(int_request_tx)})
                        .detach();

    println!("Currently disconnected.");
    println!("Type !h <newline> for command help");

    'l: for msg in int_request_rx.iter() {
        match msg {
            Request::Quit => break,
            Request::SendMessage(msg) => match msg.as_str_vec().as_slice() {
                ["!c", dest] => match Client::new(dest) {
                    Ok(client) => {
                        let quit = client_main_loop(client, &int_request_rx);
                        println!("Disconnected");

                        if quit { break 'l };
                    },
                    Err(e) => println!("{}", e)
                },
                ["!h"] => commands(),
                ["!q"] => return,
                _ => println!("can't do that, disconnected!")
            }
        }
    }

    println!("Quitting");
}

fn stdin_loop(
    request_tx: Sender<Request>
) {
    let mut u = Unpacker::new();

    for line in std::io::stdin().lock().lines() {
        match line {
            Ok(l) => send_message(&request_tx, &mut u, l.as_slice()),
            Err(e) => {
                println!("{}", e);
                return;
            }
        }
    }

    request_tx.send(Request::Quit);
}

fn send_message(tx: &Sender<Request>, unpacker: &mut Unpacker, message: &str) {
    for pline in unpacker.feed(message.as_slice()).iter() {
        if let [ref cmd, args..] = pline.as_slice() {
            tx.send(Request::SendMessage(Message::new(cmd, args)));
        }
    }
}

struct CliClient {
    /// The last time-stamp reported by the server.
    last_time: String,

    /// Whether to report time.
    report_time: bool,

    /// A transmission channel for requests to the server.
    tx: Sender<Request>
}

impl CliClient {
    /// Creates a new CliClient.
    fn new(tx: &Sender<Request>) -> CliClient {
        CliClient { last_time:   "0:00".to_owned(),
                    report_time: true,
                    tx:          tx.clone() }
    }

    /// Toggles whether to report time.
    fn toggle_time(&mut self) {
        self.report_time = !self.report_time;
        println!("i time reporting: {}",
                 if self.report_time { "on" } else { "off" });
    }

    /// Reports the current time.
    fn report_time(&self) {
        println!("T {}", self.last_time);
    }

    /// Handles a TIME notification for this CliClient.
    fn time(&mut self, t: &str) {
        if let Some(ti) = t.parse::<i64>() {
            let d = std::time::Duration::microseconds(ti);
            let s = format!("{}{:02}:{:02}",
                if 0 < d.num_hours() { format!("{}:", d.num_hours()) }
                else                 { String::new()                 },
                d.num_minutes() % 60,
                d.num_seconds() % 60);
            if s != self.last_time {
                self.last_time = s;
                if self.report_time { self.report_time() };
            }
        }
    }

    fn forward(&self, word: &str, args: &[&str]) {
        println!("> {} {}", word, args);
        self.tx.send(Request::SendMessage(Message::new(word, args)));
    }

    fn quit(&self, entire_program: bool) -> bool {
        self.tx.send(Request::Quit);
        entire_program
    }
}

/// Returns true if the outer main loop must exit.
fn client_main_loop(Client {
    request_tx,
    response_rx
}: Client, int_request_rx: &Receiver<Request>) -> bool {
    let mut state = CliClient::new(&request_tx);

    let sel = std::comm::Select::new();

    let mut reqh = sel.handle(int_request_rx);
    unsafe { reqh.add(); }

    let mut resh = sel.handle(&response_rx);
    unsafe { resh.add(); }

    loop {
        let id = sel.wait();
        if id == reqh.id() {
            match reqh.recv_opt() {
                Ok(Request::SendMessage(msg)) =>
                  match msg.as_str_vec().as_slice() {
                    ["!d"]         => return state.quit(false),
                    ["!h"]         => commands(),
                    ["!q"]         => return state.quit(true),
                    ["!t"]         => state.report_time(),
                    ["!T"]         => state.toggle_time(),
                    [word, args..] => state.forward(word, args),
                    []             => ()
                },
                Ok(req) => request_tx.send(req),
                Err(_) => return false
            }
        } else {
            match resh.recv_opt() {
                Ok(Response::Gone) => return false,
                Ok(Response::ClientError(e)) => {
                    println!("! {}", e);
                    return false;
                },
                Ok(Response::Message(m)) => match &*m.as_str_vec() {
                    [ "TIME", t ] => state.time(t),
                    [ word, args.. ] => println!("< {} {}", word, args),
                    [] => ()
                },
                Err(_) => {
                    return false;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate mio;
extern crate docopt;
#[macro_use]
extern crate log;
extern crate rasputin;

use log::LogLevel;
use docopt::Docopt;
use mio::{EventLoop};

use rasputin::server::Server;

static USAGE: &'static str = "
rasputin - HA transactional store with a focus on usability, stability and performance.

This program is the Rasputin DB server process.

Usage:
    rasputind --help
    rasputind [--cli-port=<listening port>] [--peer-port=<listening port>] [--peers=<peers>] [--logfile=<file>] [--storage-dir=<directory>]

Options:
    --help                          Show this help message.
    --cli-port=<port>               Listening port for communication between servers.
    --peer-port=<port>              Listening port for communication with clients.
    --peers=<host1:port1,...>       List of comma-delimited peers, e.g:
                                    foo.baz.com:7777,bar.baz.com:7777
    --logfile=<path>                File to log output to instead of stdout.
    --storage-dir=<path>            Directory to store the persisted data in.
";

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

    rasputin::logging::init_logger(args.flag_logfile, LogLevel::Debug).unwrap();
    print_banner();

    let peer_port: u16 = match args.flag_peer_port {
        Some(p) => p,
        None => 7770,
    };

    let cli_port: u16 = match args.flag_cli_port {
        Some(p) => p,
        None => 8880,
    };

    let peers: Vec<String> = args.flag_peers
        .split(",")
        .map(|s| s.to_string())
        .filter(|s| s != "")
        .collect();

    Server::new(peer_port, cli_port, peers).run();
    error!("A worker thread unexpectedly exited! Shutting down.");
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_help: bool,
    flag_cli_port: Option<u16>,
    flag_peer_port: Option<u16>,
    flag_peers: String,
    flag_logfile: Option<String>,
    flag_storagedir: Option<String>,
}

fn print_banner() {
    info!("

   =    )xxxxx[:::::::::>
   H     ______ _______ _______  _____  _     _ _______ _____ __   _
  / \\   |_____/ |_____| |______ |_____] |     |    |      |   | \\  |
 |CN−|  |    \\_ |     | ______| |       |_____|    |    __|__ |  \\_|
 |___|");
}
<commit_msg>upgrayedd logo<commit_after>extern crate rustc_serialize;
extern crate mio;
extern crate docopt;
#[macro_use]
extern crate log;
extern crate rasputin;

use log::LogLevel;
use docopt::Docopt;
use mio::{EventLoop};

use rasputin::server::Server;

static USAGE: &'static str = "
rasputin - HA transactional store with a focus on usability, stability and performance.

This program is the Rasputin DB server process.

Usage:
    rasputind --help
    rasputind [--cli-port=<listening port>] [--peer-port=<listening port>] [--peers=<peers>] [--logfile=<file>] [--storage-dir=<directory>]

Options:
    --help                          Show this help message.
    --cli-port=<port>               Listening port for communication between servers.
    --peer-port=<port>              Listening port for communication with clients.
    --peers=<host1:port1,...>       List of comma-delimited peers, e.g:
                                    foo.baz.com:7777,bar.baz.com:7777
    --logfile=<path>                File to log output to instead of stdout.
    --storage-dir=<path>            Directory to store the persisted data in.
";

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

    rasputin::logging::init_logger(args.flag_logfile, LogLevel::Debug).unwrap();
    print_banner();

    let peer_port: u16 = match args.flag_peer_port {
        Some(p) => p,
        None => 7770,
    };

    let cli_port: u16 = match args.flag_cli_port {
        Some(p) => p,
        None => 8880,
    };

    let peers: Vec<String> = args.flag_peers
        .split(",")
        .map(|s| s.to_string())
        .filter(|s| s != "")
        .collect();

    Server::new(peer_port, cli_port, peers).run();
    error!("A worker thread unexpectedly exited! Shutting down.");
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_help: bool,
    flag_cli_port: Option<u16>,
    flag_peer_port: Option<u16>,
    flag_peers: String,
    flag_logfile: Option<String>,
    flag_storagedir: Option<String>,
}

fn print_banner() {
    info!("
 )xxxxx[:::::::::>
 ______ _______ _______  _____  _     _ _______ _____ __   _
 |_____/ |_____| |______ |_____] |     |    |      |   | \\  |
 |    \\_ |     | ______| |       |_____|    |    __|__ |  \\_|");
}
<|endoftext|>


<commit_before>use std::ops::{Index, IndexMut};

#[macro_use]
extern crate quick_error;

extern crate nalgebra;
use nalgebra::{DMat};

extern crate image;
use image::{ImageBuffer, Luma, DynamicImage};

type FloatType = f64;
type Mat = DMat<FloatType>;

fn horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for col in cols {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for row in rows {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn mat_to_image(mat: &Mat) -> DynamicImage {
    let mut image_buffer
        = ImageBuffer::new(mat.ncols() as u32, mat.nrows() as u32);
    for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
        let value = mat.index((y as usize, x as usize));
        let byte = (*value * 255.).round() as u8;
        *pixel = Luma([byte]);
    }
    DynamicImage::ImageLuma8(image_buffer)
}

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        Io(err: std::io::Error) {}
        Image(err: image::ImageError) {}
    }
}

fn save_as_png(mat: &Mat, filename: &str) -> Result<(), ImageSaveError> {
    let image = mat_to_image(&mat);
    let path = std::path::Path::new(filename);
    let mut file = try!(std::fs::File::create(&path)
                        .map_err(ImageSaveError::Io));
    image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
}

fn main() {
    let mut factors: Vec<Mat> = Vec::new();

    factors.push(horizontal_line(9, 0..5));
    for row in (0..9).rev() {
        factors.push(horizontal_line(row, 0..10));
    }

    factors.push(vertical_line(5..10, 0));
    for col in 1..10 {
        factors.push(vertical_line(0..10, col));
    }

    println!("factors:\n");
    for (i, factor) in factors.iter().enumerate() {
        save_as_png(&factor, &format!("factor-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut horizontal_evolving: Vec<Mat> = Vec::new();
    for start_col in 0..6 {
        horizontal_evolving.push(horizontal_line(9, start_col..(start_col + 5)));
    }

    println!("short horizontal bar that moves from left to right:\n");
    for (i, factor) in horizontal_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("horizontal-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut vertical_evolving: Vec<Mat> = Vec::new();
    for start_row in (0..6).rev() {
        vertical_evolving.push(vertical_line(start_row..(start_row + 5), 0));
    }

    println!("short vertical bar that moves from bottom to top:\n");
    for (i, factor) in vertical_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("vertical-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }
}
<commit_msg>generate some random numbers with the same seed every time<commit_after>use std::ops::{Index, IndexMut};

#[macro_use]
extern crate quick_error;

extern crate nalgebra;
use nalgebra::{DMat};

extern crate image;
use image::{ImageBuffer, Luma, DynamicImage};

extern crate rand;
use rand::{StdRng, Rng, SeedableRng, Closed01};

type FloatType = f64;
type Mat = DMat<FloatType>;

fn horizontal_line<I: Iterator<Item = usize>>(row: usize, cols: I) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for col in cols {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn vertical_line<I: Iterator<Item = usize>>(rows: I, col: usize) -> Mat {
    let mut factor: Mat = DMat::new_zeros(10, 10);
    for row in rows {
        *factor.index_mut((row, col)) = 1.;
    }
    factor
}

fn mat_to_image(mat: &Mat) -> DynamicImage {
    let mut image_buffer
        = ImageBuffer::new(mat.ncols() as u32, mat.nrows() as u32);
    for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
        let value = mat.index((y as usize, x as usize));
        let byte = (*value * 255.).round() as u8;
        *pixel = Luma([byte]);
    }
    DynamicImage::ImageLuma8(image_buffer)
}

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        Io(err: std::io::Error) {}
        Image(err: image::ImageError) {}
    }
}

fn save_as_png(mat: &Mat, filename: &str) -> Result<(), ImageSaveError> {
    let image = mat_to_image(&mat);
    let path = std::path::Path::new(filename);
    let mut file = try!(std::fs::File::create(&path)
                        .map_err(ImageSaveError::Io));
    image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
}

fn main() {
    let mut factors: Vec<Mat> = Vec::new();

    factors.push(horizontal_line(9, 0..5));
    for row in (0..9).rev() {
        factors.push(horizontal_line(row, 0..10));
    }

    factors.push(vertical_line(5..10, 0));
    for col in 1..10 {
        factors.push(vertical_line(0..10, col));
    }

    println!("factors:\n");
    for (i, factor) in factors.iter().enumerate() {
        save_as_png(&factor, &format!("factor-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut horizontal_evolving: Vec<Mat> = Vec::new();
    for start_col in 0..6 {
        horizontal_evolving.push(horizontal_line(9, start_col..(start_col + 5)));
    }

    println!("short horizontal bar that moves from left to right:\n");
    for (i, factor) in horizontal_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("horizontal-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let mut vertical_evolving: Vec<Mat> = Vec::new();
    for start_row in (0..6).rev() {
        vertical_evolving.push(vertical_line(start_row..(start_row + 5), 0));
    }

    println!("short vertical bar that moves from bottom to top:\n");
    for (i, factor) in vertical_evolving.iter().enumerate() {
        save_as_png(&factor, &format!("vertical-{}.png", i)[..]).unwrap();
        println!("{:?}", factor);
    }

    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    for _ in 0..10 {
        let Closed01(val) = rng.gen::<Closed01<f64>>();
        println!("{}", val);
    }
}
<|endoftext|>


<commit_before>use std::ops::Deref;
use std::rc::Rc;
use std::cell::RefCell;
use super::Position;
use super::GapBuffer;

/// Read-only wrapper for a `Position`, to allow field level access to a
/// buffer's cursor while simultaneously enforcing bounds-checking when
/// updating its value.
pub struct Cursor {
    pub data: Rc<RefCell<GapBuffer>>,
    pub position: Position,
}

impl Deref for Cursor {
    type Target = Position;

    fn deref(&self) -> &Position {
        &self.position
    }
}

impl Cursor {
    /// Moves the cursor to the specified location. The location is
    /// bounds-checked against the data and the cursor will not be
    /// updated if it is out-of-bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// let in_bounds = scribe::buffer::Position{ line: 0, offset: 2 };
    /// let out_of_bounds = scribe::buffer::Position{ line: 2, offset: 2 };
    /// buffer.insert("scribe");
    ///
    /// buffer.cursor.move_to(in_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    ///
    /// buffer.cursor.move_to(out_of_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    /// ```
    pub fn move_to(&mut self, position: Position) -> bool {
        if self.data.borrow().in_bounds(&position) {
            self.position = position;
            return true
        }
        false
    }

    /// Decrements the cursor line. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_up(&mut self) {
        let target_line = self.line-1;
        let new_position = Position{ line: target_line, offset: self.offset };

        // Don't even bother if the target line is negative.
        if target_line < 0 { return }

        // Try moving to the same offset on the line above, falling back to its EOL.
        if self.move_to(new_position) == false {
            let mut target_offset = 0;
            for (line_number, line) in self.data.borrow().to_string().lines().enumerate() {
                if line_number == target_line {
                    target_offset = line.len();
                }
            }
            self.move_to(Position{ line: target_line, offset: target_offset });
        }
    }

    /// Increments the cursor line. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_down(&mut self) {
        let new_position = Position{ line: self.line+1, offset: self.offset };
        self.move_to(new_position);
    }

    /// Decrements the cursor offset. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_left(&mut self) {
        let new_position = Position{ line: self.line, offset: self.offset-1 };
        self.move_to(new_position);
    }

    /// Increments the cursor offset. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_right(&mut self) {
        let new_position = Position{ line: self.line, offset: self.offset+1 };
        self.move_to(new_position);
    }
}

#[cfg(test)]
mod tests {
    use super::Cursor;
    use super::super::gap_buffer;
    use super::super::Position;
    use std::rc::Rc;
    use std::cell::RefCell;

    #[test]
    fn move_up_goes_to_EOL_if_offset_would_be_out_of_range() {
        let mut buffer = Rc::new(RefCell::new(gap_buffer::new("This is a test.\nAnother line that is longer.".to_string())));
        let position = Position{ line: 1, offset: 20 };
        let mut cursor = Cursor{ data: buffer, position: position };
        cursor.move_up();
        assert_eq!(cursor.line, 0);
        assert_eq!(cursor.offset, 15);
    }
}
<commit_msg>Extend move_down to go to EOL if current offset doesn't exist.<commit_after>use std::ops::Deref;
use std::rc::Rc;
use std::cell::RefCell;
use super::Position;
use super::GapBuffer;

/// Read-only wrapper for a `Position`, to allow field level access to a
/// buffer's cursor while simultaneously enforcing bounds-checking when
/// updating its value.
pub struct Cursor {
    pub data: Rc<RefCell<GapBuffer>>,
    pub position: Position,
}

impl Deref for Cursor {
    type Target = Position;

    fn deref(&self) -> &Position {
        &self.position
    }
}

impl Cursor {
    /// Moves the cursor to the specified location. The location is
    /// bounds-checked against the data and the cursor will not be
    /// updated if it is out-of-bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// let mut buffer = scribe::buffer::new();
    /// let in_bounds = scribe::buffer::Position{ line: 0, offset: 2 };
    /// let out_of_bounds = scribe::buffer::Position{ line: 2, offset: 2 };
    /// buffer.insert("scribe");
    ///
    /// buffer.cursor.move_to(in_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    ///
    /// buffer.cursor.move_to(out_of_bounds);
    /// assert_eq!(buffer.cursor.line, 0);
    /// assert_eq!(buffer.cursor.offset, 2);
    /// ```
    pub fn move_to(&mut self, position: Position) -> bool {
        if self.data.borrow().in_bounds(&position) {
            self.position = position;
            return true
        }
        false
    }

    /// Decrements the cursor line. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_up(&mut self) {
        let target_line = self.line-1;
        let new_position = Position{ line: target_line, offset: self.offset };

        // Don't even bother if the target line is negative.
        if target_line < 0 { return }

        // Try moving to the same offset on the line above, falling back to its EOL.
        if self.move_to(new_position) == false {
            let mut target_offset = 0;
            for (line_number, line) in self.data.borrow().to_string().lines().enumerate() {
                if line_number == target_line {
                    target_offset = line.len();
                }
            }
            self.move_to(Position{ line: target_line, offset: target_offset });
        }
    }

    /// Increments the cursor line. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_down(&mut self) {
        let target_line = self.line+1;
        let new_position = Position{ line: target_line, offset: self.offset };

        // Try moving to the same offset on the line below, falling back to its EOL.
        if self.move_to(new_position) == false {
            let mut target_offset = 0;
            for (line_number, line) in self.data.borrow().to_string().lines().enumerate() {
                if line_number == target_line {
                    target_offset = line.len();
                }
            }
            self.move_to(Position{ line: target_line, offset: target_offset });
        }
    }

    /// Decrements the cursor offset. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_left(&mut self) {
        let new_position = Position{ line: self.line, offset: self.offset-1 };
        self.move_to(new_position);
    }

    /// Increments the cursor offset. The location is bounds-checked against
    /// the data and the cursor will not be updated if it is out-of-bounds.
    pub fn move_right(&mut self) {
        let new_position = Position{ line: self.line, offset: self.offset+1 };
        self.move_to(new_position);
    }
}

#[cfg(test)]
mod tests {
    use super::Cursor;
    use super::super::gap_buffer;
    use super::super::Position;
    use std::rc::Rc;
    use std::cell::RefCell;

    #[test]
    fn move_up_goes_to_EOL_if_offset_would_be_out_of_range() {
        let mut buffer = Rc::new(RefCell::new(gap_buffer::new("This is a test.\nAnother line that is longer.".to_string())));
        let position = Position{ line: 1, offset: 20 };
        let mut cursor = Cursor{ data: buffer, position: position };
        cursor.move_up();
        assert_eq!(cursor.line, 0);
        assert_eq!(cursor.offset, 15);
    }

    #[test]
    fn move_down_goes_to_EOL_if_offset_would_be_out_of_range() {
        let mut buffer = Rc::new(RefCell::new(gap_buffer::new("Another line that is longer.\nThis is a test.".to_string())));
        let position = Position{ line: 0, offset: 20 };
        let mut cursor = Cursor{ data: buffer, position: position };
        cursor.move_down();
        assert_eq!(cursor.line, 1);
        assert_eq!(cursor.offset, 15);
    }
}
<|endoftext|>


<commit_before>use super::Command;

extern crate chrono;

use lib::fs::*;
use lib::io::*;
use lib::setting::*;
use self::chrono::Local;
use std::fs;
use std::path::PathBuf;

pub struct Sweep;

impl Command for Sweep {
    fn validation(&self) -> bool { true }

    fn help_message(&self) -> &'static str {
        return "sweep!";
    }

    fn main(&self) {
        println!("Sweep ...\n");

        let now  = Local::now();
        let date = now.format("%Y-%m-%d").to_string();

        let path_to_dust_box = path_buf![storage_dir(), date, "dusts"];
        create_essential_dir_all(&path_to_dust_box);

        let ignore = read_ignore_file();

        let target_files = walk_dir(".")
            .difference(&ignore)
            .cloned()
            .collect::<Vec<String>>();
        move_files_to_dust_box(target_files, &path_to_dust_box);

        move_empty_dir_to_dust_box(&path_to_dust_box);
    }
}

fn move_files_to_dust_box(target_files: Vec<String>, path_to_dust_box: &PathBuf) {
    for target in &target_files {
        let target_path = path_buf![&target];
        let target_name = match extract_file_name(&target_path) {
            Some(file_name) => file_name,
            None            => panic!(format_with_tag(1, Tag::Error, "Cannot convert the file name to UTF-8")),
        };
        let target_base = match target_path.parent() {
            Some(base_name) => base_name,
            None            => panic!(format_with_tag(1, Tag::Error, "Cannot convert the base name")),
        };
        let to = path_buf![&path_to_dust_box, target_base];

        create_essential_dir_all(&to);

        print_with_tag(0, Tag::Execution, format!("Move \"{}\" to dust box", target_name));

        // forcedly overwrite if the file exists with same name.
        match fs::rename(target, path_buf![to, target_name]) {
            Ok(_)    => print_with_tag(1, Tag::Okay, "Moved the file to dust box"),
            Err(why) => panic!(format_with_tag(1, Tag::Error, why)),
        }
    }
}

fn move_empty_dir_to_dust_box(path_to_dust_box: &PathBuf) {
    let all_dirs = dirs_ordered_by_descending_depth(".");
    for dir in all_dirs.iter().filter(|d| *d != ".") {
        print_with_tag(0, Tag::Execution, format!("EXECUTION: Remove \"{}\" directory", dir));

        match fs::remove_dir(dir) {
            Ok(_) => {
                print_with_tag(1, Tag::Okay, "Removed the directory");
                create_essential_dir_all(&path_buf![&path_to_dust_box, dir]);
            },
            Err(why) => match why.raw_os_error() {
                Some(39) => print_with_tag(1, Tag::Notice, "The directory is not empty. Cancelled to remove it"),
                _        => panic!(format_with_tag(1, Tag::Error, why)),
            },
        }
    }
}
<commit_msg>[Remedy] Enforce the output messages<commit_after>use super::Command;

extern crate chrono;

use lib::fs::*;
use lib::io::*;
use lib::setting::*;
use self::chrono::Local;
use std::fs;
use std::path::PathBuf;

pub struct Sweep;

impl Command for Sweep {
    fn validation(&self) -> bool { true }

    fn help_message(&self) -> &'static str {
        return "sweep!";
    }

    fn main(&self) {
        println!("Sweep ...\n");

        let now  = Local::now();
        let date = now.format("%Y-%m-%d").to_string();

        let path_to_dust_box = path_buf![storage_dir(), date, "dusts"];
        create_essential_dir_all(&path_to_dust_box);

        let ignore = read_ignore_file();

        let target_files = walk_dir(".")
            .difference(&ignore)
            .cloned()
            .collect::<Vec<String>>();
        move_files_to_dust_box(target_files, &path_to_dust_box);

        move_empty_dir_to_dust_box(&path_to_dust_box);
    }
}

fn move_files_to_dust_box(target_files: Vec<String>, path_to_dust_box: &PathBuf) {
    for target in &target_files {
        print_with_tag(0, Tag::Execution, "Analyze the path to file");

        let target_path = path_buf![&target];
        let target_name = match extract_file_name(&target_path) {
            Some(file_name) => file_name,
            None            => panic!(format_with_tag(1, Tag::Error, "Cannot convert the file name to UTF-8")),
        };
        let target_base = match target_path.parent() {
            Some(base_name) => base_name,
            None            => panic!(format_with_tag(1, Tag::Error, "Cannot extract the base name")),
        };
        let to = path_buf![&path_to_dust_box, target_base];

        print_with_tag(1, Tag::Okay, "Analyzed the path to file");

        create_essential_dir_all(&to);

        print_with_tag(0, Tag::Execution, format!("Move \"{}\" to dust box", target_name));

        // forcedly overwrite if the file exists with same name.
        match fs::rename(target, path_buf![to, target_name]) {
            Ok(_)    => print_with_tag(1, Tag::Okay, "Moved the file to dust box"),
            Err(why) => panic!(format_with_tag(1, Tag::Error, why)),
        }
    }
}

fn move_empty_dir_to_dust_box(path_to_dust_box: &PathBuf) {
    let all_dirs = dirs_ordered_by_descending_depth(".");
    for dir in all_dirs.iter().filter(|d| *d != ".") {
        print_with_tag(0, Tag::Execution, format!("EXECUTION: Remove \"{}\" directory", dir));

        match fs::remove_dir(dir) {
            Ok(_) => {
                print_with_tag(1, Tag::Okay, "Removed the directory");
                create_essential_dir_all(&path_buf![&path_to_dust_box, dir]);
            },
            Err(why) => match why.raw_os_error() {
                Some(39) => print_with_tag(1, Tag::Notice, "The directory is not empty. Cancelled to remove it"),
                _        => panic!(format_with_tag(1, Tag::Error, why)),
            },
        }
    }
}
<|endoftext|>