<commit_before>extern crate rand;
extern crate termion;
extern crate unicode_segmentation;

use std::collections::{BTreeMap, VecDeque};
use std::io::Write;
use std::io::{stdout, Result, Stdout};
use std::thread;
use std::time::Duration;

use termion::cursor::DetectCursorPos;
use termion::raw::IntoRawMode;
use termion::raw::RawTerminal;
use termion::{clear, color, cursor};
use unicode_segmentation::UnicodeSegmentation;

enum Console {
  Terminal(RawTerminal<Stdout>),
  Pipe(Stdout),
}

pub struct EngineDisplay {
  sigil: char,
  divider: String,
  poll_interval_ms: Duration,
  padding: String,
  terminal: Console,
  action_map: BTreeMap<String, String>,
  logs: VecDeque<String>,
  running: bool,
  is_tty: bool,
  cursor_start: (u16, u16),
  terminal_size: (u16, u16),
}

// TODO: Prescribe a threading/polling strategy for callers - or implement a built-in one.
// TODO: Better error handling for .flush() and .write() failure modes.
// TODO: Permit scrollback in the terminal - both at exit and during the live run.
impl EngineDisplay {
  pub fn for_stdout(indent_level: u16) -> EngineDisplay {
    let write_handle = stdout();
    let is_tty = termion::is_tty(&write_handle);

    EngineDisplay {
      sigil: '⚡',
      divider: "▵".to_string(),
      poll_interval_ms: Duration::from_millis(55),
      padding: " ".repeat(indent_level.into()),
      terminal: if !is_tty {
        Console::Pipe(write_handle)
      } else {
        match write_handle.into_raw_mode() {
          Ok(t) => Console::Terminal(t),
          Err(_) => Console::Pipe(stdout()),
        }
      },
      action_map: BTreeMap::new(),
      // This is arbitrary based on a guesstimated peak terminal row size for modern displays.
      // The reason this can't be capped to e.g. the starting size is because of resizing - we
      // want to be able to fill the entire screen if resized much larger than when we started.
      logs: VecDeque::with_capacity(500),
      running: false,
      is_tty: is_tty,
      // N.B. This will cause the screen to clear - but with some improved position
      // tracking logic we could avoid screen clearing in favor of using the value
      // of `EngineDisplay::get_cursor_pos()` as initialization here. From there, the
      // trick would be to push the on-screen text screen up (ideally, prior to entering
      // raw mode) via newline printing - and then ensuring the rendered text never
      // overflows past the screen row bounds. Before we could safely do that tho, we
      // probably want to plumb a signal handler for SIGWINCH so that ^L works to redraw
      // the screen in the case of any display issues. Otherwise, simply clearing the screen
      // as we've done here is the safest way to avoid terminal oddness.
      cursor_start: (1, 1),
      terminal_size: EngineDisplay::get_size(),
    }
  }

  // Gets the current terminal's cursor position, if applicable.
  fn get_cursor_pos(&mut self) -> (u16, u16) {
    match self.terminal {
      // N.B. Real TTY coordinates start at (1, 1).
      Console::Terminal(ref mut t) => t.cursor_pos().unwrap_or((0, 0)),
      Console::Pipe(_) => (0, 0),
    }
  }

  // Gets the current terminal's width and height, if applicable.
  fn get_size() -> (u16, u16) {
    termion::terminal_size().unwrap_or((0, 0))
  }

  // Whether or not the EngineDisplay is running (whether .start() has been called).
  pub fn is_running(&self) -> bool {
    self.running
  }

  // Sets the terminal size per-render for signal-free resize detection.
  fn set_size(&mut self) {
    self.terminal_size = EngineDisplay::get_size();
  }

  // Sets the terminal size for signal-free resize detection.
  fn get_max_log_rows(&self) -> usize {
    // TODO: If the terminal size is smaller than the action map, we should fall back
    // to non-tty mode output to avoid.
    self.terminal_size.1 as usize - self.action_map.len() - 1
  }

  // Prep the screen for painting by clearing it from the cursor start position.
  fn clear(&mut self) {
    let cursor_start = self.cursor_start;
    self
      .write(&format!(
        "{goto_origin}{clear}",
        goto_origin = cursor::Goto(cursor_start.0, cursor_start.1),
        clear = clear::AfterCursor,
      ))
      .expect("could not write to terminal");
  }

  // Flush terminal output.
  fn flush(&mut self) -> Result<()> {
    match self.terminal {
      Console::Terminal(ref mut t) => t.flush(),
      Console::Pipe(ref mut p) => p.flush(),
    }
  }

  // Writes output to the terminal.
  fn write(&mut self, msg: &str) -> Result<usize> {
    match self.terminal {
      Console::Terminal(ref mut t) => t.write(msg.as_bytes()),
      Console::Pipe(ref mut p) => p.write(msg.as_bytes()),
    }
  }

  // Renders a divider between the logs and action output.
  fn render_divider(&mut self, offset: u16) {
    let cursor_start = self.cursor_start;
    let padding = self.padding.clone();
    let divider = self.divider.clone();

    self
      .write(&format!(
        "{pos}{clear_line}{padding}{blue}{divider}{reset}",
        pos = cursor::Goto(1, cursor_start.1 + offset),
        clear_line = clear::CurrentLine,
        padding = padding,
        blue = color::Fg(color::Blue),
        divider = divider,
        reset = color::Fg(color::Reset)
      ))
      .expect("could not write to terminal");
  }

  // Renders one frame of the log portion of the screen.
  fn render_logs(&mut self, max_entries: usize) -> usize {
    let cursor_start = self.cursor_start;
    let printable_logs: Vec<String> = self.logs.clone().into_iter().take(max_entries).collect();

    let mut counter: usize = 0;
    for (n, log_entry) in printable_logs.iter().rev().enumerate() {
      counter += 1;
      let line_shortened_log_entry: String = format!(
        "{padding}{log_entry}",
        padding = self.padding,
        log_entry = log_entry
      ).graphemes(true)
        .take(self.terminal_size.0 as usize)
        .collect();

      self
        .write(&format!(
          "{pos}{clear_line}{entry}",
          pos = cursor::Goto(1, cursor_start.1 + n as u16),
          clear_line = clear::CurrentLine,
          entry = line_shortened_log_entry
        ))
        .expect("could not write to terminal");
    }

    if counter > 0 {
      self.render_divider(counter as u16);
      counter += 1;
    }
    counter
  }

  // Renders one frame of the action portion of the screen.
  fn render_actions(&mut self, start_row: usize) {
    let cursor_start = self.cursor_start;
    let worker_states = self.action_map.clone();

    // For every active worker in the action map, jump to the exact cursor
    // representing the swimlane for this worker and lay down a text label.
    for (n, (_worker_id, action)) in worker_states.iter().enumerate() {
      let line_shortened_output: String = format!(
          "{padding}{blue}{sigil}{reset}{action}",
          padding=self.padding,
          blue=color::Fg(color::LightBlue),
          sigil=self.sigil,
          reset=color::Fg(color::Reset),
          action=action
        )
        .graphemes(true)
        // Account for control characters.
        .take(self.terminal_size.0 as usize + 14)
        .collect();

      self
        .write(&format!(
          "{pos}{entry}",
          pos = cursor::Goto(1, cursor_start.1 + start_row as u16 + n as u16),
          entry = line_shortened_output
        ))
        .expect("could not write to terminal");
    }
  }

  fn render_for_pipe(&self) {
    // TODO: Handle non-tty output w polling interval adjustment + summary rendering.
    panic!("TODO");
  }

  // Paints one screen of rendering.
  fn render_for_tty(&mut self) {
    self.set_size();
    self.clear();
    let max_log_rows = self.get_max_log_rows();
    let rendered_count = self.render_logs(max_log_rows);
    self.render_actions(rendered_count);
    self.flush().expect("could not flush terminal!");
  }

  // Paints one screen of rendering.
  pub fn render(&mut self) {
    // TODO: Split this fork out into sub-types of EngineDisplay.
    match self.is_tty {
      true => self.render_for_tty(),
      false => self.render_for_pipe(),
    }
  }

  // Paints one screen of rendering and sleeps for the poll interval.
  pub fn render_and_sleep(&mut self) {
    self.render();
    thread::sleep(self.poll_interval_ms);
  }

  // Starts the EngineDisplay at the current cursor position.
  pub fn start(&mut self) {
    self.running = true;
    let cursor_start = self.cursor_start;
    self
      .write(&format!(
        "{hide_cursor}{cursor_init}{clear_after_cursor}",
        hide_cursor = termion::cursor::Hide,
        cursor_init = cursor::Goto(cursor_start.0, cursor_start.1),
        clear_after_cursor = clear::AfterCursor
      ))
      .expect("could not write to terminal");
  }

  // Adds a worker/thread to the visual representation.
  pub fn add_worker(&mut self, worker_name: String) {
    let action_msg = format!("booting {}", worker_name);
    self.update(worker_name, action_msg);
  }

  // Updates the status of a worker/thread.
  pub fn update(&mut self, worker_name: String, action: String) {
    self.action_map.insert(worker_name, action);
  }

  // Removes a worker/thread from the visual representation.
  pub fn remove_worker(&mut self, worker_id: &str) {
    self.action_map.remove(worker_id);
  }

  // Adds a log entry for display.
  pub fn log(&mut self, log_entry: String) {
    self.logs.push_front(log_entry)
  }

  // Terminates the EngineDisplay and returns the cursor to a static position.
  pub fn finish(&mut self) {
    self.running = false;
    let current_pos = self.get_cursor_pos();
    let action_count = self.action_map.len() as u16;
    self
      .write(&format!(
        "{park_cursor}{clear_after_cursor}{reveal_cursor}",
        park_cursor = cursor::Goto(1, current_pos.1 - action_count),
        clear_after_cursor = clear::AfterCursor,
        reveal_cursor = termion::cursor::Show
      ))
      .expect("could not write to terminal");
  }
}
<commit_msg>Only clone taken Strings, not all Strings (#6240)<commit_after>extern crate rand;
extern crate termion;
extern crate unicode_segmentation;

use std::collections::{BTreeMap, VecDeque};
use std::io::Write;
use std::io::{stdout, Result, Stdout};
use std::thread;
use std::time::Duration;

use termion::cursor::DetectCursorPos;
use termion::raw::IntoRawMode;
use termion::raw::RawTerminal;
use termion::{clear, color, cursor};
use unicode_segmentation::UnicodeSegmentation;

enum Console {
  Terminal(RawTerminal<Stdout>),
  Pipe(Stdout),
}

pub struct EngineDisplay {
  sigil: char,
  divider: String,
  poll_interval_ms: Duration,
  padding: String,
  terminal: Console,
  action_map: BTreeMap<String, String>,
  logs: VecDeque<String>,
  running: bool,
  is_tty: bool,
  cursor_start: (u16, u16),
  terminal_size: (u16, u16),
}

// TODO: Prescribe a threading/polling strategy for callers - or implement a built-in one.
// TODO: Better error handling for .flush() and .write() failure modes.
// TODO: Permit scrollback in the terminal - both at exit and during the live run.
impl EngineDisplay {
  pub fn for_stdout(indent_level: u16) -> EngineDisplay {
    let write_handle = stdout();
    let is_tty = termion::is_tty(&write_handle);

    EngineDisplay {
      sigil: '⚡',
      divider: "▵".to_string(),
      poll_interval_ms: Duration::from_millis(55),
      padding: " ".repeat(indent_level.into()),
      terminal: if !is_tty {
        Console::Pipe(write_handle)
      } else {
        match write_handle.into_raw_mode() {
          Ok(t) => Console::Terminal(t),
          Err(_) => Console::Pipe(stdout()),
        }
      },
      action_map: BTreeMap::new(),
      // This is arbitrary based on a guesstimated peak terminal row size for modern displays.
      // The reason this can't be capped to e.g. the starting size is because of resizing - we
      // want to be able to fill the entire screen if resized much larger than when we started.
      logs: VecDeque::with_capacity(500),
      running: false,
      is_tty: is_tty,
      // N.B. This will cause the screen to clear - but with some improved position
      // tracking logic we could avoid screen clearing in favor of using the value
      // of `EngineDisplay::get_cursor_pos()` as initialization here. From there, the
      // trick would be to push the on-screen text screen up (ideally, prior to entering
      // raw mode) via newline printing - and then ensuring the rendered text never
      // overflows past the screen row bounds. Before we could safely do that tho, we
      // probably want to plumb a signal handler for SIGWINCH so that ^L works to redraw
      // the screen in the case of any display issues. Otherwise, simply clearing the screen
      // as we've done here is the safest way to avoid terminal oddness.
      cursor_start: (1, 1),
      terminal_size: EngineDisplay::get_size(),
    }
  }

  // Gets the current terminal's cursor position, if applicable.
  fn get_cursor_pos(&mut self) -> (u16, u16) {
    match self.terminal {
      // N.B. Real TTY coordinates start at (1, 1).
      Console::Terminal(ref mut t) => t.cursor_pos().unwrap_or((0, 0)),
      Console::Pipe(_) => (0, 0),
    }
  }

  // Gets the current terminal's width and height, if applicable.
  fn get_size() -> (u16, u16) {
    termion::terminal_size().unwrap_or((0, 0))
  }

  // Whether or not the EngineDisplay is running (whether .start() has been called).
  pub fn is_running(&self) -> bool {
    self.running
  }

  // Sets the terminal size per-render for signal-free resize detection.
  fn set_size(&mut self) {
    self.terminal_size = EngineDisplay::get_size();
  }

  // Sets the terminal size for signal-free resize detection.
  fn get_max_log_rows(&self) -> usize {
    // TODO: If the terminal size is smaller than the action map, we should fall back
    // to non-tty mode output to avoid.
    self.terminal_size.1 as usize - self.action_map.len() - 1
  }

  // Prep the screen for painting by clearing it from the cursor start position.
  fn clear(&mut self) {
    let cursor_start = self.cursor_start;
    self
      .write(&format!(
        "{goto_origin}{clear}",
        goto_origin = cursor::Goto(cursor_start.0, cursor_start.1),
        clear = clear::AfterCursor,
      ))
      .expect("could not write to terminal");
  }

  // Flush terminal output.
  fn flush(&mut self) -> Result<()> {
    match self.terminal {
      Console::Terminal(ref mut t) => t.flush(),
      Console::Pipe(ref mut p) => p.flush(),
    }
  }

  // Writes output to the terminal.
  fn write(&mut self, msg: &str) -> Result<usize> {
    match self.terminal {
      Console::Terminal(ref mut t) => t.write(msg.as_bytes()),
      Console::Pipe(ref mut p) => p.write(msg.as_bytes()),
    }
  }

  // Renders a divider between the logs and action output.
  fn render_divider(&mut self, offset: u16) {
    let cursor_start = self.cursor_start;
    let padding = self.padding.clone();
    let divider = self.divider.clone();

    self
      .write(&format!(
        "{pos}{clear_line}{padding}{blue}{divider}{reset}",
        pos = cursor::Goto(1, cursor_start.1 + offset),
        clear_line = clear::CurrentLine,
        padding = padding,
        blue = color::Fg(color::Blue),
        divider = divider,
        reset = color::Fg(color::Reset)
      ))
      .expect("could not write to terminal");
  }

  // Renders one frame of the log portion of the screen.
  fn render_logs(&mut self, max_entries: usize) -> usize {
    let cursor_start = self.cursor_start;
    let printable_logs: Vec<String> = self.logs.iter().take(max_entries).cloned().collect();

    let mut counter: usize = 0;
    for (n, log_entry) in printable_logs.iter().rev().enumerate() {
      counter += 1;
      let line_shortened_log_entry: String = format!(
        "{padding}{log_entry}",
        padding = self.padding,
        log_entry = log_entry
      ).graphemes(true)
        .take(self.terminal_size.0 as usize)
        .collect();

      self
        .write(&format!(
          "{pos}{clear_line}{entry}",
          pos = cursor::Goto(1, cursor_start.1 + n as u16),
          clear_line = clear::CurrentLine,
          entry = line_shortened_log_entry
        ))
        .expect("could not write to terminal");
    }

    if counter > 0 {
      self.render_divider(counter as u16);
      counter += 1;
    }
    counter
  }

  // Renders one frame of the action portion of the screen.
  fn render_actions(&mut self, start_row: usize) {
    let cursor_start = self.cursor_start;
    let worker_states = self.action_map.clone();

    // For every active worker in the action map, jump to the exact cursor
    // representing the swimlane for this worker and lay down a text label.
    for (n, (_worker_id, action)) in worker_states.iter().enumerate() {
      let line_shortened_output: String = format!(
          "{padding}{blue}{sigil}{reset}{action}",
          padding=self.padding,
          blue=color::Fg(color::LightBlue),
          sigil=self.sigil,
          reset=color::Fg(color::Reset),
          action=action
        )
        .graphemes(true)
        // Account for control characters.
        .take(self.terminal_size.0 as usize + 14)
        .collect();

      self
        .write(&format!(
          "{pos}{entry}",
          pos = cursor::Goto(1, cursor_start.1 + start_row as u16 + n as u16),
          entry = line_shortened_output
        ))
        .expect("could not write to terminal");
    }
  }

  fn render_for_pipe(&self) {
    // TODO: Handle non-tty output w polling interval adjustment + summary rendering.
    panic!("TODO");
  }

  // Paints one screen of rendering.
  fn render_for_tty(&mut self) {
    self.set_size();
    self.clear();
    let max_log_rows = self.get_max_log_rows();
    let rendered_count = self.render_logs(max_log_rows);
    self.render_actions(rendered_count);
    self.flush().expect("could not flush terminal!");
  }

  // Paints one screen of rendering.
  pub fn render(&mut self) {
    // TODO: Split this fork out into sub-types of EngineDisplay.
    match self.is_tty {
      true => self.render_for_tty(),
      false => self.render_for_pipe(),
    }
  }

  // Paints one screen of rendering and sleeps for the poll interval.
  pub fn render_and_sleep(&mut self) {
    self.render();
    thread::sleep(self.poll_interval_ms);
  }

  // Starts the EngineDisplay at the current cursor position.
  pub fn start(&mut self) {
    self.running = true;
    let cursor_start = self.cursor_start;
    self
      .write(&format!(
        "{hide_cursor}{cursor_init}{clear_after_cursor}",
        hide_cursor = termion::cursor::Hide,
        cursor_init = cursor::Goto(cursor_start.0, cursor_start.1),
        clear_after_cursor = clear::AfterCursor
      ))
      .expect("could not write to terminal");
  }

  // Adds a worker/thread to the visual representation.
  pub fn add_worker(&mut self, worker_name: String) {
    let action_msg = format!("booting {}", worker_name);
    self.update(worker_name, action_msg);
  }

  // Updates the status of a worker/thread.
  pub fn update(&mut self, worker_name: String, action: String) {
    self.action_map.insert(worker_name, action);
  }

  // Removes a worker/thread from the visual representation.
  pub fn remove_worker(&mut self, worker_id: &str) {
    self.action_map.remove(worker_id);
  }

  // Adds a log entry for display.
  pub fn log(&mut self, log_entry: String) {
    self.logs.push_front(log_entry)
  }

  // Terminates the EngineDisplay and returns the cursor to a static position.
  pub fn finish(&mut self) {
    self.running = false;
    let current_pos = self.get_cursor_pos();
    let action_count = self.action_map.len() as u16;
    self
      .write(&format!(
        "{park_cursor}{clear_after_cursor}{reveal_cursor}",
        park_cursor = cursor::Goto(1, current_pos.1 - action_count),
        clear_after_cursor = clear::AfterCursor,
        reveal_cursor = termion::cursor::Show
      ))
      .expect("could not write to terminal");
  }
}
<|endoftext|>


<commit_before>#[doc = "

Pulls a brief description out of a long description.

If the first paragraph of a long description is short enough then it
is interpreted as the brief description.

"];

export mk_pass;

fn mk_pass() -> pass {
    {
        name: "desc_to_brief",
        f: run
    }
}

fn run(
    _srv: astsrv::srv,
    doc: doc::doc
) -> doc::doc {
    let fold = fold::fold({
        fold_item: fold_item,
        fold_iface: fold_iface,
        fold_impl: fold_impl
        with *fold::default_any_fold(())
    });
    fold.fold_doc(fold, doc)
}

fn fold_item(fold: fold::fold<()>, doc: doc::itemdoc) -> doc::itemdoc {
    let doc = fold::default_seq_fold_item(fold, doc);

    {
        brief: extract(doc.desc)
        with doc
    }
}

fn fold_iface(fold: fold::fold<()>, doc: doc::ifacedoc) -> doc::ifacedoc {
    let doc =fold::default_seq_fold_iface(fold, doc);

    {
        methods: par::anymap(doc.methods) {|doc|
            {
                brief: extract(doc.desc)
                with doc
            }
        }
        with doc
    }
}

fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
    let doc =fold::default_seq_fold_impl(fold, doc);

    {
        methods: par::anymap(doc.methods) {|doc|
            {
                brief: extract(doc.desc)
                with doc
            }
        }
        with doc
    }
}

#[test]
fn should_promote_desc() {
    let doc = test::mk_doc("#[doc = \"desc\"] mod m { }");
    assert doc.cratemod().mods()[0].brief() == some("desc");
}

#[test]
fn should_promote_iface_method_desc() {
    let doc = test::mk_doc("iface i { #[doc = \"desc\"] fn a(); }");
    assert doc.cratemod().ifaces()[0].methods[0].brief == some("desc");
}

#[test]
fn should_promote_impl_method_desc() {
    let doc = test::mk_doc(
        "impl i for int { #[doc = \"desc\"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].brief == some("desc");
}

#[cfg(test)]
mod test {
    fn mk_doc(source: str) -> doc::doc {
        astsrv::from_str(source) {|srv|
            let doc = extract::from_srv(srv, "");
            let doc = attr_pass::mk_pass().f(srv, doc);
            run(srv, doc)
        }
    }
}

fn extract(desc: option<str>) -> option<str> {
    if option::is_none(desc) {
        ret none
    }

    parse_desc(option::get(desc))
}

fn parse_desc(desc: str) -> option<str> {

    const max_brief_len: uint = 120u;

    let paras = paragraphs(desc);

    if check vec::is_not_empty(paras) {
        let maybe_brief = vec::head(paras);
        if str::len(maybe_brief) <= max_brief_len {
            some(maybe_brief)
        } else {
            none
        }
    } else {
        none
    }
}

fn paragraphs(s: str) -> [str] {
    let lines = str::lines_any(s);
    let whitespace_lines = 0;
    let accum = "";
    let paras = vec::foldl([], lines) {|paras, line|
        let res = paras;

        if str::is_whitespace(line) {
            whitespace_lines += 1;
        } else {
            if whitespace_lines > 0 {
                if str::is_not_empty(accum) {
                    res += [accum];
                    accum = "";
                }
            }

            whitespace_lines = 0;

            accum = if str::is_empty(accum) {
                line
            } else {
                accum + "\n" + line
            }
        }

        res
    };

    if str::is_not_empty(accum) {
        paras + [accum]
    } else {
        paras
    }
}

#[test]
fn test_paragraphs_1() {
    let paras = paragraphs("1\n\n2");
    assert paras == ["1", "2"];
}

#[test]
fn test_paragraphs_2() {
    let paras = paragraphs("\n\n1\n1\n\n2\n\n");
    assert paras == ["1\n1", "2"];
}

#[test]
fn should_promote_short_descs() {
    let desc = some("desc");
    let brief = extract(desc);
    assert brief == desc;
}

#[test]
fn should_not_promote_long_descs() {
    let desc = some("Warkworth Castle is a ruined medieval building
in the town of the same name in the English county of Northumberland.
The town and castle occupy a loop of the River Coquet, less than a mile
from England's north-east coast. When the castle was founded is uncertain,
but traditionally its construction has been ascribed to Prince Henry of
Scotland in the mid 12th century, although it may have been built by
King Henry II of England when he took control of England'snorthern
counties.");
    let brief = extract(desc);
    assert brief == none;
}
<commit_msg>rustdoc: Accept the first sentence as the brief description<commit_after>#[doc = "

Pulls a brief description out of a long description.

If the first paragraph of a long description is short enough then it
is interpreted as the brief description.

"];

export mk_pass;

fn mk_pass() -> pass {
    {
        name: "desc_to_brief",
        f: run
    }
}

fn run(
    _srv: astsrv::srv,
    doc: doc::doc
) -> doc::doc {
    let fold = fold::fold({
        fold_item: fold_item,
        fold_iface: fold_iface,
        fold_impl: fold_impl
        with *fold::default_any_fold(())
    });
    fold.fold_doc(fold, doc)
}

fn fold_item(fold: fold::fold<()>, doc: doc::itemdoc) -> doc::itemdoc {
    let doc = fold::default_seq_fold_item(fold, doc);

    {
        brief: extract(doc.desc)
        with doc
    }
}

fn fold_iface(fold: fold::fold<()>, doc: doc::ifacedoc) -> doc::ifacedoc {
    let doc =fold::default_seq_fold_iface(fold, doc);

    {
        methods: par::anymap(doc.methods) {|doc|
            {
                brief: extract(doc.desc)
                with doc
            }
        }
        with doc
    }
}

fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
    let doc =fold::default_seq_fold_impl(fold, doc);

    {
        methods: par::anymap(doc.methods) {|doc|
            {
                brief: extract(doc.desc)
                with doc
            }
        }
        with doc
    }
}

#[test]
fn should_promote_desc() {
    let doc = test::mk_doc("#[doc = \"desc\"] mod m { }");
    assert doc.cratemod().mods()[0].brief() == some("desc");
}

#[test]
fn should_promote_iface_method_desc() {
    let doc = test::mk_doc("iface i { #[doc = \"desc\"] fn a(); }");
    assert doc.cratemod().ifaces()[0].methods[0].brief == some("desc");
}

#[test]
fn should_promote_impl_method_desc() {
    let doc = test::mk_doc(
        "impl i for int { #[doc = \"desc\"] fn a() { } }");
    assert doc.cratemod().impls()[0].methods[0].brief == some("desc");
}

#[cfg(test)]
mod test {
    fn mk_doc(source: str) -> doc::doc {
        astsrv::from_str(source) {|srv|
            let doc = extract::from_srv(srv, "");
            let doc = attr_pass::mk_pass().f(srv, doc);
            run(srv, doc)
        }
    }
}

fn extract(desc: option<str>) -> option<str> {
    if option::is_none(desc) {
        ret none
    }

    parse_desc(option::get(desc))
}

fn parse_desc(desc: str) -> option<str> {

    const max_brief_len: uint = 120u;

    alt first_sentence(desc) {
      some(first_sentence) {
        if str::len(first_sentence) <= max_brief_len {
            some(first_sentence)
        } else {
            none
        }
      }
      none { none }
    }
}

fn first_sentence(s: str) -> option<str> {
    let paras = paragraphs(s);
    if vec::is_not_empty(paras) {
        let first = vec::head(sentences(vec::head(paras)));
        some(str::replace(first, "\n", " "))
    } else {
        none
    }
}

fn sentences(s: str) -> [str] {
    str::split_char(s, '.')
}

fn paragraphs(s: str) -> [str] {
    let lines = str::lines_any(s);
    let whitespace_lines = 0;
    let accum = "";
    let paras = vec::foldl([], lines) {|paras, line|
        let res = paras;

        if str::is_whitespace(line) {
            whitespace_lines += 1;
        } else {
            if whitespace_lines > 0 {
                if str::is_not_empty(accum) {
                    res += [accum];
                    accum = "";
                }
            }

            whitespace_lines = 0;

            accum = if str::is_empty(accum) {
                line
            } else {
                accum + "\n" + line
            }
        }

        res
    };

    if str::is_not_empty(accum) {
        paras + [accum]
    } else {
        paras
    }
}

#[test]
fn test_paragraphs_1() {
    let paras = paragraphs("1\n\n2");
    assert paras == ["1", "2"];
}

#[test]
fn test_paragraphs_2() {
    let paras = paragraphs("\n\n1\n1\n\n2\n\n");
    assert paras == ["1\n1", "2"];
}

#[test]
fn should_promote_short_descs() {
    let desc = some("desc");
    let brief = extract(desc);
    assert brief == desc;
}

#[test]
fn should_not_promote_long_descs() {
    let desc = some("Warkworth Castle is a ruined medieval building
in the town of the same name in the English county of Northumberland,
and the town and castle occupy a loop of the River Coquet, less than a mile
from England's north-east coast. When the castle was founded is uncertain,
but traditionally its construction has been ascribed to Prince Henry of
Scotland in the mid 12th century, although it may have been built by
King Henry II of England when he took control of England'snorthern
counties.");
    let brief = extract(desc);
    assert brief == none;
}

#[test]
fn should_promote_first_sentence() {
    let desc = some("Warkworth Castle is a ruined medieval building
in the town. of the same name in the English county of Northumberland,
and the town and castle occupy a loop of the River Coquet, less than a mile
from England's north-east coast. When the castle was founded is uncertain,
but traditionally its construction has been ascribed to Prince Henry of
Scotland in the mid 12th century, although it may have been built by
King Henry II of England when he took control of England'snorthern
counties.");
    let brief = extract(desc);
    assert brief == some(
        "Warkworth Castle is a ruined medieval building in the town");
}<|endoftext|>


<commit_before>include!("../sorting.in");

use super::Sorts;

impl Sorts for SortedVector {
    fn sort(&mut self) {
        for j in 1..self.vector.len() {
            let x = self.vector[j];
            let mut i: i32 = j as i32 - 1;

            while i >= 0 && x < self.vector[i as usize] {
                self.vector[(i + 1) as usize] = self.vector[i as usize];
                i -= 1;
            }
            self.vector[(i + 1) as usize] = x;
        }
    }
}
<commit_msg>Fix sorting_insertion bydlocode<commit_after>include!("../sorting.in");

use super::Sorts;

impl Sorts for SortedVector {
    fn sort(&mut self) {
        for j in 1..self.vector.len() {
            let x = self.vector[j];
            let mut i = j;

            while i > 0 && x < self.vector[i - 1] {
                self.vector[i] = self.vector[i - 1];
                i -= 1;
            }
            self.vector[i] = x;
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use std::env;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let target_dir = env::var("CARGO_TARGET_DIR").unwrap();
    let profile_dir = env::var("PROFILE").unwrap();
    let dest = format!("{}/{}/{}", target_dir, profile_dir, "simpleservo.h");
    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .with_language(cbindgen::Language::C)
        .exclude_item("OutputDebugStringA")
        .generate()
        .expect("Unable to generate bindings")
        .write_to_file(dest);
}
<commit_msg>Generate simpleservo.h in appropriate target directory.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use std::env;
use std::path::PathBuf;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let target_dir = env::var("CARGO_TARGET_DIR").unwrap();
    let mut path: PathBuf = [crate_dir.clone(), target_dir].iter().collect();
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    if target != host {
        path.push(target);
    }
    let profile_dir = env::var("PROFILE").unwrap();
    path.push(profile_dir);
    path.push("simpleservo.h");
    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .with_language(cbindgen::Language::C)
        .exclude_item("OutputDebugStringA")
        .generate()
        .expect("Unable to generate bindings")
        .write_to_file(path);
}
<|endoftext|>


<commit_before>//! Performs various peephole optimizations.

use crate::transform::MirPass;
use rustc_hir::Mutability;
use rustc_middle::mir::{
    BinOp, Body, Constant, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo,
    StatementKind,
};
use rustc_middle::ty::{self, TyCtxt};

pub struct InstCombine;

impl<'tcx> MirPass<'tcx> for InstCombine {
    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
        let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
        let ctx = InstCombineContext { tcx, local_decls };
        for block in basic_blocks.iter_mut() {
            for statement in block.statements.iter_mut() {
                match statement.kind {
                    StatementKind::Assign(box (_place, ref mut rvalue)) => {
                        ctx.combine_bool_cmp(&statement.source_info, rvalue);
                        ctx.combine_ref_deref(&statement.source_info, rvalue);
                        ctx.combine_len(&statement.source_info, rvalue);
                    }
                    _ => {}
                }
            }
        }
    }
}

struct InstCombineContext<'tcx, 'a> {
    tcx: TyCtxt<'tcx>,
    local_decls: &'a LocalDecls<'tcx>,
}

impl<'tcx, 'a> InstCombineContext<'tcx, 'a> {
    fn should_combine(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
        self.tcx.consider_optimizing(|| {
            format!("InstCombine - Rvalue: {:?} SourceInfo: {:?}", rvalue, source_info)
        })
    }

    /// Transform boolean comparisons into logical operations.
    fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        match rvalue {
            Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => {
                let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) {
                    // Transform "Eq(a, true)" ==> "a"
                    (BinOp::Eq, _, Some(true)) => Some(a.clone()),

                    // Transform "Ne(a, false)" ==> "a"
                    (BinOp::Ne, _, Some(false)) => Some(a.clone()),

                    // Transform "Eq(true, b)" ==> "b"
                    (BinOp::Eq, Some(true), _) => Some(b.clone()),

                    // Transform "Ne(false, b)" ==> "b"
                    (BinOp::Ne, Some(false), _) => Some(b.clone()),

                    // FIXME: Consider combining remaining comparisons into logical operations:
                    // Transform "Eq(false, b)" ==> "Not(b)"
                    // Transform "Ne(true, b)" ==> "Not(b)"
                    // Transform "Eq(a, false)" ==> "Not(a)"
                    // Transform "Ne(a, true)" ==> "Not(a)"
                    _ => None,
                };

                if let Some(new) = new {
                    if self.should_combine(source_info, rvalue) {
                        *rvalue = Rvalue::Use(new);
                    }
                }
            }

            _ => {}
        }
    }

    fn try_eval_bool(&self, a: &Operand<'_>) -> Option<bool> {
        let a = a.constant()?;
        if a.literal.ty.is_bool() { a.literal.val.try_to_bool() } else { None }
    }

    /// Transform "&(*a)" ==> "a".
    fn combine_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        if let Rvalue::Ref(_, _, place) = rvalue {
            if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
                if let ty::Ref(_, _, Mutability::Not) =
                    base.ty(self.local_decls, self.tcx).ty.kind()
                {
                    // The dereferenced place must have type `&_`, so that we don't copy `&mut _`.
                } else {
                    return;
                }

                if !self.should_combine(source_info, rvalue) {
                    return;
                }

                *rvalue = Rvalue::Use(Operand::Copy(Place {
                    local: base.local,
                    projection: self.tcx.intern_place_elems(base.projection),
                }));
            }
        }
    }

    /// Transform "Len([_; N])" ==> "N".
    fn combine_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        if let Rvalue::Len(ref place) = *rvalue {
            let place_ty = place.ty(self.local_decls, self.tcx).ty;
            if let ty::Array(_, len) = place_ty.kind() {
                if !self.should_combine(source_info, rvalue) {
                    return;
                }

                let constant = Constant { span: source_info.span, literal: len, user_ty: None };
                *rvalue = Rvalue::Use(Operand::Constant(box constant));
            }
        }
    }
}
<commit_msg>remove assignments to ZST places<commit_after>//! Performs various peephole optimizations.

use crate::transform::MirPass;
use rustc_hir::Mutability;
use rustc_middle::mir::{
    BinOp, Body, Constant, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo,
    StatementKind,
};
use rustc_middle::ty::{self, TyCtxt};

pub struct InstCombine;

impl<'tcx> MirPass<'tcx> for InstCombine {
    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
        let param_env = tcx.param_env(body.source.def_id());
        let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
        let ctx = InstCombineContext { tcx, local_decls, param_env };
        for block in basic_blocks.iter_mut() {
            for statement in block.statements.iter_mut() {
                ctx.combine_zst(&statement.source_info, &mut statement.kind);
                match statement.kind {
                    StatementKind::Assign(box (_place, ref mut rvalue)) => {
                        ctx.combine_bool_cmp(&statement.source_info, rvalue);
                        ctx.combine_ref_deref(&statement.source_info, rvalue);
                        ctx.combine_len(&statement.source_info, rvalue);
                    }
                    _ => {}
                }
            }
        }
    }
}

struct InstCombineContext<'tcx, 'a> {
    tcx: TyCtxt<'tcx>,
    local_decls: &'a LocalDecls<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
}

impl<'tcx, 'a> InstCombineContext<'tcx, 'a> {
    fn should_combine(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
        self.tcx.consider_optimizing(|| {
            format!("InstCombine - Rvalue: {:?} SourceInfo: {:?}", rvalue, source_info)
        })
    }

    /// Remove assignments to inhabited ZST places.
    fn combine_zst(&self, source_info: &SourceInfo, kind: &mut StatementKind<'tcx>) {
        match kind {
            StatementKind::Assign(box (place, _)) => {
                let place_ty = place.ty(self.local_decls, self.tcx).ty;
                if let Ok(layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
                    if layout.is_zst() && !layout.abi.is_uninhabited() {
                        if self.tcx.consider_optimizing(|| {
                            format!(
                                "InstCombine ZST - Place: {:?} SourceInfo: {:?}",
                                place, source_info
                            )
                        }) {
                            *kind = StatementKind::Nop;
                        }
                    }
                }
            }
            _ => {}
        }
    }

    /// Transform boolean comparisons into logical operations.
    fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        match rvalue {
            Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => {
                let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) {
                    // Transform "Eq(a, true)" ==> "a"
                    (BinOp::Eq, _, Some(true)) => Some(a.clone()),

                    // Transform "Ne(a, false)" ==> "a"
                    (BinOp::Ne, _, Some(false)) => Some(a.clone()),

                    // Transform "Eq(true, b)" ==> "b"
                    (BinOp::Eq, Some(true), _) => Some(b.clone()),

                    // Transform "Ne(false, b)" ==> "b"
                    (BinOp::Ne, Some(false), _) => Some(b.clone()),

                    // FIXME: Consider combining remaining comparisons into logical operations:
                    // Transform "Eq(false, b)" ==> "Not(b)"
                    // Transform "Ne(true, b)" ==> "Not(b)"
                    // Transform "Eq(a, false)" ==> "Not(a)"
                    // Transform "Ne(a, true)" ==> "Not(a)"
                    _ => None,
                };

                if let Some(new) = new {
                    if self.should_combine(source_info, rvalue) {
                        *rvalue = Rvalue::Use(new);
                    }
                }
            }

            _ => {}
        }
    }

    fn try_eval_bool(&self, a: &Operand<'_>) -> Option<bool> {
        let a = a.constant()?;
        if a.literal.ty.is_bool() { a.literal.val.try_to_bool() } else { None }
    }

    /// Transform "&(*a)" ==> "a".
    fn combine_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        if let Rvalue::Ref(_, _, place) = rvalue {
            if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
                if let ty::Ref(_, _, Mutability::Not) =
                    base.ty(self.local_decls, self.tcx).ty.kind()
                {
                    // The dereferenced place must have type `&_`, so that we don't copy `&mut _`.
                } else {
                    return;
                }

                if !self.should_combine(source_info, rvalue) {
                    return;
                }

                *rvalue = Rvalue::Use(Operand::Copy(Place {
                    local: base.local,
                    projection: self.tcx.intern_place_elems(base.projection),
                }));
            }
        }
    }

    /// Transform "Len([_; N])" ==> "N".
    fn combine_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
        if let Rvalue::Len(ref place) = *rvalue {
            let place_ty = place.ty(self.local_decls, self.tcx).ty;
            if let ty::Array(_, len) = place_ty.kind() {
                if !self.should_combine(source_info, rvalue) {
                    return;
                }

                let constant = Constant { span: source_info.span, literal: len, user_ty: None };
                *rvalue = Rvalue::Use(Operand::Constant(box constant));
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate gannai;
extern crate argparse;
extern crate rand;
extern crate rustc_serialize;

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

use rustc_serialize::json;

use gannai::neural_network::{ApplyConf, NetworkBuf, Network};

struct Args {
    conf: String,
    network: String,
}

fn main() {
    let mut args = Args {conf: String::new(), network: String::new()};
    parse_args(&mut args);
    let conf = make_conf(&args);
    let network_buf = make_network_buf(&args);
    apply(&conf, &network_buf.as_network());
}

fn parse_args(args: &mut Args) {
    use argparse::{ArgumentParser, Store};
    let mut parser = ArgumentParser::new();
    parser.set_description("Applies neural network to input data");
    parser.refer(&mut args.conf)
        .add_argument("conf", Store, "Path to conf json file").required();
    parser.refer(&mut args.network)
        .add_argument("network", Store, "Path to neural network json file").required();
    parser.parse_args_or_exit();
}

fn make_conf(args: &Args) -> ApplyConf {
    let mut data = String::new();
    File::open(&args.conf).unwrap().read_to_string(&mut data).unwrap();
    json::decode(&data).unwrap()
}

fn make_network_buf(args: &Args) -> NetworkBuf {
    let mut data = String::new();
    File::open(&args.network).unwrap().read_to_string(&mut data).unwrap();
    json::decode(&data).unwrap()
}

fn apply(conf: &ApplyConf, network: &Network) {
    use std::io::{BufRead, stdin};
    use gannai::neural_network::Apply;
    let application = network.apply(&conf);
    let file = stdin();
    for line in file.lock().lines() {
        let data = line.unwrap();
        let input: Vec<f64> = json::decode(&data).unwrap();
        let output = application.perform(&input[..]);
        println!("{}", json::encode(&output).unwrap());
    }
}
<commit_msg>Change input and output format for apply tool<commit_after>extern crate gannai;
extern crate argparse;
extern crate rand;
extern crate rustc_serialize;

use rustc_serialize::json;

use gannai::neural_network::{ApplyConf, Network};
use gannai::tools::common::{make_conf, make_network_buf};

struct Args {
    conf: String,
    network: String,
}

fn main() {
    let mut args = Args {conf: String::new(), network: String::new()};
    parse_args(&mut args);
    let conf = make_conf::<ApplyConf>(&args.conf);
    let network_buf = make_network_buf(&args.network);
    apply(&conf, &network_buf.as_network());
}

fn parse_args(args: &mut Args) {
    use argparse::{ArgumentParser, Store};
    let mut parser = ArgumentParser::new();
    parser.set_description("Applies neural network to input data");
    parser.refer(&mut args.conf)
        .add_argument("conf", Store, "Path to conf json file").required();
    parser.refer(&mut args.network)
        .add_argument("network", Store, "Path to neural network json file").required();
    parser.parse_args_or_exit();
}

fn apply(conf: &ApplyConf, network: &Network) {
    use std::io::{BufRead, stdin};
    use gannai::neural_network::Apply;
    let application = network.apply(&conf);
    let file = stdin();
    for line in file.lock().lines() {
        let data = line.unwrap();
        let input: Input = json::decode(&data).unwrap();
        let output_values = application.perform(&input.input[..]);
        let output = Output {input: input.input, output: output_values};
        println!("{}", json::encode(&output).unwrap());
    }
}

#[derive(RustcDecodable)]
struct Input {
    input: Vec<f64>,
}

#[derive(RustcEncodable)]
struct Output {
    input: Vec<f64>,
    output: Vec<f64>,
}
<|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use common::Config;

/// Conversion table from triple OS name to Rust SYSNAME
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
    ("android", "android"),
    ("bitrig", "bitrig"),
    ("cloudabi", "cloudabi"),
    ("darwin", "macos"),
    ("dragonfly", "dragonfly"),
    ("freebsd", "freebsd"),
    ("haiku", "haiku"),
    ("ios", "ios"),
    ("linux", "linux"),
    ("mingw32", "windows"),
    ("netbsd", "netbsd"),
    ("openbsd", "openbsd"),
    ("win32", "windows"),
    ("windows", "windows"),
    ("solaris", "solaris"),
    ("emscripten", "emscripten"),
];

const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
    ("aarch64", "aarch64"),
    ("amd64", "x86_64"),
    ("arm", "arm"),
    ("arm64", "aarch64"),
    ("hexagon", "hexagon"),
    ("i386", "x86"),
    ("i586", "x86"),
    ("i686", "x86"),
    ("mips64", "mips64"),
    ("mips", "mips"),
    ("msp430", "msp430"),
    ("powerpc", "powerpc"),
    ("powerpc64", "powerpc64"),
    ("s390x", "s390x"),
    ("sparc", "sparc"),
    ("x86_64", "x86_64"),
    ("xcore", "xcore"),
    ("asmjs", "asmjs"),
    ("wasm32", "wasm32"),
];

pub fn matches_os(triple: &str, name: &str) -> bool {
    // For the wasm32 bare target we ignore anything also ignored on emscripten
    // and then we also recognize `wasm32-bare` as the os for the target
    if triple == "wasm32-unknown-unknown" {
        return name == "emscripten" || name == "wasm32-bare"
    }
    for &(triple_os, os) in OS_TABLE {
        if triple.contains(triple_os) {
            return os == name;
        }
    }
    panic!("Cannot determine OS from triple");
}
pub fn get_arch(triple: &str) -> &'static str {
    for &(triple_arch, arch) in ARCH_TABLE {
        if triple.contains(triple_arch) {
            return arch;
        }
    }
    panic!("Cannot determine Architecture from triple");
}

pub fn get_env(triple: &str) -> Option<&str> {
    triple.split('-').nth(3)
}

pub fn get_pointer_width(triple: &str) -> &'static str {
    if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") {
        "64bit"
    } else {
        "32bit"
    }
}

pub fn make_new_path(path: &str) -> String {
    assert!(cfg!(windows));
    // Windows just uses PATH as the library search path, so we have to
    // maintain the current value while adding our own
    match env::var(lib_path_env_var()) {
        Ok(curr) => format!("{}{}{}", path, path_div(), curr),
        Err(..) => path.to_owned(),
    }
}

pub fn lib_path_env_var() -> &'static str {
    "PATH"
}
fn path_div() -> &'static str {
    ";"
}

pub fn logv(config: &Config, s: String) {
    debug!("{}", s);
    if config.verbose {
        println!("{}", s);
    }
}
<commit_msg>Add more canonicalisations for OS_TABLE and ARCH_TABLE<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use common::Config;

/// Conversion table from triple OS name to Rust SYSNAME
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
    ("android", "android"),
    ("androideabi", "android"),
    ("bitrig", "bitrig"),
    ("cloudabi", "cloudabi"),
    ("darwin", "macos"),
    ("dragonfly", "dragonfly"),
    ("emscripten", "emscripten"),
    ("freebsd", "freebsd"),
    ("fuchsia", "fuchsia"),
    ("haiku", "haiku"),
    ("ios", "ios"),
    ("l4re", "l4re"),
    ("linux", "linux"),
    ("mingw32", "windows"),
    ("netbsd", "netbsd"),
    ("openbsd", "openbsd"),
    ("redox", "redox"),
    ("solaris", "solaris"),
    ("win32", "windows"),
    ("windows", "windows"),
];

const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
    ("aarch64", "aarch64"),
    ("amd64", "x86_64"),
    ("arm", "arm"),
    ("arm64", "aarch64"),
    ("armv4t", "arm"),
    ("armv5te", "arm"),
    ("armv7", "arm"),
    ("armv7s", "arm"),
    ("asmjs", "asmjs"),
    ("hexagon", "hexagon"),
    ("i386", "x86"),
    ("i586", "x86"),
    ("i686", "x86"),
    ("mips", "mips"),
    ("mips64", "mips64"),
    ("mips64el", "mips64"),
    ("mipsel", "mips"),
    ("msp430", "msp430"),
    ("powerpc", "powerpc"),
    ("powerpc64", "powerpc64"),
    ("powerpc64le", "powerpc64"),
    ("s390x", "s390x"),
    ("sparc", "sparc"),
    ("sparc64", "sparc64"),
    ("sparcv9", "sparc64"),
    ("thumbv6m", "thumb"),
    ("thumbv7em", "thumb"),
    ("thumbv7m", "thumb"),
    ("wasm32", "wasm32"),
    ("x86_64", "x86_64"),
    ("xcore", "xcore"),
];

pub fn matches_os(triple: &str, name: &str) -> bool {
    // For the wasm32 bare target we ignore anything also ignored on emscripten
    // and then we also recognize `wasm32-bare` as the os for the target
    if triple == "wasm32-unknown-unknown" {
        return name == "emscripten" || name == "wasm32-bare"
    }
    for &(triple_os, os) in OS_TABLE {
        if triple.contains(triple_os) {
            return os == name;
        }
    }
    panic!("Cannot determine OS from triple");
}
pub fn get_arch(triple: &str) -> &'static str {
    for &(triple_arch, arch) in ARCH_TABLE {
        if triple.contains(triple_arch) {
            return arch;
        }
    }
    panic!("Cannot determine Architecture from triple");
}

pub fn get_env(triple: &str) -> Option<&str> {
    triple.split('-').nth(3)
}

pub fn get_pointer_width(triple: &str) -> &'static str {
    if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") {
        "64bit"
    } else {
        "32bit"
    }
}

pub fn make_new_path(path: &str) -> String {
    assert!(cfg!(windows));
    // Windows just uses PATH as the library search path, so we have to
    // maintain the current value while adding our own
    match env::var(lib_path_env_var()) {
        Ok(curr) => format!("{}{}{}", path, path_div(), curr),
        Err(..) => path.to_owned(),
    }
}

pub fn lib_path_env_var() -> &'static str {
    "PATH"
}
fn path_div() -> &'static str {
    ";"
}

pub fn logv(config: &Config, s: String) {
    debug!("{}", s);
    if config.verbose {
        println!("{}", s);
    }
}
<|endoftext|>


<commit_before>// spell-checker:ignore (URL) appspot

use crate::numeric::*;

pub(crate) trait Basis {
    const BASIS: &'static [u64];
}

impl Basis for Montgomery<u64> {
    // Small set of bases for the Miller-Rabin prime test, valid for all 64b integers;
    //  discovered by Jim Sinclair on 2011-04-20, see miller-rabin.appspot.com
    #[allow(clippy::unreadable_literal)]
    const BASIS: &'static [u64] = &[2, 325, 9375, 28178, 450775, 9780504, 1795265022];
}

impl Basis for Montgomery<u32> {
    // Small set of bases for the Miller-Rabin prime test, valid for all 32b integers;
    //  discovered by Steve Worley on 2013-05-27, see miller-rabin.appspot.com
    #[allow(clippy::unreadable_literal)]
    const BASIS: &'static [u64] = &[
        4230279247111683200,
        14694767155120705706,
        16641139526367750375,
    ];
}

#[derive(Eq, PartialEq)]
pub(crate) enum Result {
    Prime,
    Pseudoprime,
    Composite(u64),
}

impl Result {
    pub(crate) fn is_prime(&self) -> bool {
        *self == Result::Prime
    }
}

// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
// (some) dividers; it will fail to factor strong pseudoprimes.
#[allow(clippy::many_single_char_names)]
pub(crate) fn test<A: Arithmetic + Basis>(m: A) -> Result {
    use self::Result::*;

    let n = m.modulus();
    if n < 2 {
        return Pseudoprime;
    }
    if n % 2 == 0 {
        return if n == 2 { Prime } else { Composite(2) };
    }

    // n-1 = r 2ⁱ
    let i = (n - 1).trailing_zeros();
    let r = (n - 1) >> i;

    let one = m.one();
    let minus_one = m.minus_one();

    for _a in A::BASIS.iter() {
        let _a = _a % n;
        if _a == 0 {
            break;
        }

        let a = m.from_u64(_a);

        // x = a^r mod n
        let mut x = m.pow(a, r);

        {
            // y = ((x²)²...)² i times = x ^ (2ⁱ) = a ^ (r 2ⁱ) = x ^ (n - 1)
            let mut y = x;
            for _ in 0..i {
                y = m.mul(y, y)
            }
            if y != one {
                return Pseudoprime;
            };
        }

        if x == one || x == minus_one {
            continue;
        }

        loop {
            let y = m.mul(x, x);
            if y == one {
                return Composite(gcd(m.to_u64(x) - 1, m.modulus()));
            }
            if y == minus_one {
                // This basis element is not a witness of `n` being composite.
                // Keep looking.
                break;
            }
            x = y;
        }
    }

    Prime
}

// Used by build.rs' tests and debug assertions
#[allow(dead_code)]
pub(crate) fn is_prime(n: u64) -> bool {
    if n % 2 == 0 {
        n == 2
    } else {
        test::<Montgomery<u64>>(Montgomery::new(n)).is_prime()
    }
}

#[cfg(test)]
mod tests {
    use super::is_prime;
    const LARGEST_U64_PRIME: u64 = 0xFFFFFFFFFFFFFFC5;

    #[test]
    fn largest_prime() {
        assert!(is_prime(LARGEST_U64_PRIME));
    }

    #[test]
    fn first_primes() {
        use crate::table::{NEXT_PRIME, P_INVS_U64};
        for (p, _, _) in P_INVS_U64.iter() {
            assert!(is_prime(*p), "{} reported composite", p);
        }
        assert!(is_prime(NEXT_PRIME));
    }

    #[test]
    fn issue_1556() {
        // 10 425 511 = 2441 × 4271
        assert!(!is_prime(10_425_511));
    }

    #[test]
    fn small_composites() {
        use crate::table::P_INVS_U64;

        for i in 0..P_INVS_U64.len() {
            let (p, _, _) = P_INVS_U64[i];
            for (q, _, _) in &P_INVS_U64[0..i] {
                let n = p * q;
                assert!(!is_prime(n), "{} = {} × {} reported prime", n, p, q);
            }
        }
    }
}
<commit_msg>factor::miller_rabin: Add test for the largest 64b composite numbers<commit_after>// spell-checker:ignore (URL) appspot

use crate::numeric::*;

pub(crate) trait Basis {
    const BASIS: &'static [u64];
}

impl Basis for Montgomery<u64> {
    // Small set of bases for the Miller-Rabin prime test, valid for all 64b integers;
    //  discovered by Jim Sinclair on 2011-04-20, see miller-rabin.appspot.com
    #[allow(clippy::unreadable_literal)]
    const BASIS: &'static [u64] = &[2, 325, 9375, 28178, 450775, 9780504, 1795265022];
}

impl Basis for Montgomery<u32> {
    // Small set of bases for the Miller-Rabin prime test, valid for all 32b integers;
    //  discovered by Steve Worley on 2013-05-27, see miller-rabin.appspot.com
    #[allow(clippy::unreadable_literal)]
    const BASIS: &'static [u64] = &[
        4230279247111683200,
        14694767155120705706,
        16641139526367750375,
    ];
}

#[derive(Eq, PartialEq)]
pub(crate) enum Result {
    Prime,
    Pseudoprime,
    Composite(u64),
}

impl Result {
    pub(crate) fn is_prime(&self) -> bool {
        *self == Result::Prime
    }
}

// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
// (some) dividers; it will fail to factor strong pseudoprimes.
#[allow(clippy::many_single_char_names)]
pub(crate) fn test<A: Arithmetic + Basis>(m: A) -> Result {
    use self::Result::*;

    let n = m.modulus();
    if n < 2 {
        return Pseudoprime;
    }
    if n % 2 == 0 {
        return if n == 2 { Prime } else { Composite(2) };
    }

    // n-1 = r 2ⁱ
    let i = (n - 1).trailing_zeros();
    let r = (n - 1) >> i;

    let one = m.one();
    let minus_one = m.minus_one();

    for _a in A::BASIS.iter() {
        let _a = _a % n;
        if _a == 0 {
            break;
        }

        let a = m.from_u64(_a);

        // x = a^r mod n
        let mut x = m.pow(a, r);

        {
            // y = ((x²)²...)² i times = x ^ (2ⁱ) = a ^ (r 2ⁱ) = x ^ (n - 1)
            let mut y = x;
            for _ in 0..i {
                y = m.mul(y, y)
            }
            if y != one {
                return Pseudoprime;
            };
        }

        if x == one || x == minus_one {
            continue;
        }

        loop {
            let y = m.mul(x, x);
            if y == one {
                return Composite(gcd(m.to_u64(x) - 1, m.modulus()));
            }
            if y == minus_one {
                // This basis element is not a witness of `n` being composite.
                // Keep looking.
                break;
            }
            x = y;
        }
    }

    Prime
}

// Used by build.rs' tests and debug assertions
#[allow(dead_code)]
pub(crate) fn is_prime(n: u64) -> bool {
    if n % 2 == 0 {
        n == 2
    } else {
        test::<Montgomery<u64>>(Montgomery::new(n)).is_prime()
    }
}

#[cfg(test)]
mod tests {
    use super::is_prime;
    const LARGEST_U64_PRIME: u64 = 0xFFFFFFFFFFFFFFC5;

    #[test]
    fn largest_prime() {
        assert!(is_prime(LARGEST_U64_PRIME));
    }

    #[test]
    fn largest_composites() {
        for i in LARGEST_U64_PRIME + 1..=u64::MAX {
            assert!(!is_prime(i), "2⁶⁴ - {} reported prime", u64::MAX - i + 1);
        }
    }

    #[test]
    fn first_primes() {
        use crate::table::{NEXT_PRIME, P_INVS_U64};
        for (p, _, _) in P_INVS_U64.iter() {
            assert!(is_prime(*p), "{} reported composite", p);
        }
        assert!(is_prime(NEXT_PRIME));
    }

    #[test]
    fn issue_1556() {
        // 10 425 511 = 2441 × 4271
        assert!(!is_prime(10_425_511));
    }

    #[test]
    fn small_composites() {
        use crate::table::P_INVS_U64;

        for i in 0..P_INVS_U64.len() {
            let (p, _, _) = P_INVS_U64[i];
            for (q, _, _) in &P_INVS_U64[0..i] {
                let n = p * q;
                assert!(!is_prime(n), "{} = {} × {} reported prime", n, p, q);
            }
        }
    }
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/A%2BB#Go
use std::io::stdio::stdin;
use std::from_str::from_str;
use std::io::buffered::BufferedReader;

fn main() {
    let input = BufferedReader::new(stdin()).read_line().unwrap();
    let mut words = input.words();

    let sum = match (words.next().and_then(from_str::<int>), words.next().and_then(from_str)) {
        (Some(a), Some(b)) => a + b,
        _                  => fail!("Please enter 2 integers")
    };

    println!("{:i}", sum);
}<commit_msg>Fixed a+b.rs import<commit_after>// Implements http://rosettacode.org/wiki/A%2BB#Go
use std::io::stdio::stdin;
use std::from_str::from_str;
use std::io::BufferedReader;

fn main() {
    let input = BufferedReader::new(stdin()).read_line().unwrap();
    let mut words = input.words();

    let sum = match (words.next().and_then(from_str::<int>), words.next().and_then(from_str)) {
        (Some(a), Some(b)) => a + b,
        _                  => fail!("Please enter 2 integers")
    };

    println!("{:i}", sum);
}
<|endoftext|>


<commit_before>use crate::schema::*;

use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
use rustc_serialize::opaque::Encoder;
use std::slice;
use std::u32;
use log::debug;

/// While we are generating the metadata, we also track the position
/// of each DefIndex. It is not required that all definitions appear
/// in the metadata, nor that they are serialized in order, and
/// therefore we first allocate the vector here and fill it with
/// `u32::MAX`. Whenever an index is visited, we fill in the
/// appropriate spot by calling `record_position`. We should never
/// visit the same index twice.
pub struct Index {
    positions: [Vec<u32>; 2]
}

impl Index {
    pub fn new((max_index_lo, max_index_hi): (usize, usize)) -> Index {
        Index {
            positions: [vec![u32::MAX; max_index_lo],
                        vec![u32::MAX; max_index_hi]],
        }
    }

    pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'_>>) {
        assert!(def_id.is_local());
        self.record_index(def_id.index, entry);
    }

    pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'_>>) {
        assert!(entry.position < (u32::MAX as usize));
        let position = entry.position as u32;
        let space_index = item.address_space().index();
        let array_index = item.as_array_index();

        assert!(self.positions[space_index][array_index] == u32::MAX,
                "recorded position for item {:?} twice, first at {:?} and now at {:?}",
                item,
                self.positions[space_index][array_index],
                position);

        self.positions[space_index][array_index] = position.to_le();
    }

    pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
        let pos = buf.position();

        // First we write the length of the lower range ...
        buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
        // ... then the values in the lower range ...
        buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
        // ... then the values in the higher range.
        buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
        LazySeq::with_position_and_length(pos as usize,
            self.positions[0].len() + self.positions[1].len() + 1)
    }
}

impl<'tcx> LazySeq<Index> {
    /// Given the metadata, extract out the offset of a particular
    /// DefIndex (if any).
    #[inline(never)]
    pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
        let words = &bytes_to_words(&bytes[self.position..])[..self.len];

        debug!("Index::lookup: index={:?} words.len={:?}",
               def_index,
               words.len());

        let positions = match def_index.address_space() {
            DefIndexAddressSpace::Low => &words[1..],
            DefIndexAddressSpace::High => {
                // This is a DefIndex in the higher range, so find out where
                // that starts:
                let lo_count = u32::from_le(words[0].get()) as usize;
                &words[lo_count + 1 .. ]
            }
        };

        let array_index = def_index.as_array_index();
        let position = u32::from_le(positions[array_index].get());
        if position == u32::MAX {
            debug!("Index::lookup: position=u32::MAX");
            None
        } else {
            debug!("Index::lookup: position={:?}", position);
            Some(Lazy::with_position(position as usize))
        }
    }
}

#[repr(packed)]
#[derive(Copy)]
struct Unaligned<T>(T);

// The derived Clone impl is unsafe for this packed struct since it needs to pass a reference to
// the field to `T::clone`, but this reference may not be properly aligned.
impl<T: Copy> Clone for Unaligned<T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<T> Unaligned<T> {
    fn get(self) -> T { self.0 }
}

fn bytes_to_words(b: &[u8]) -> &[Unaligned<u32>] {
    unsafe { slice::from_raw_parts(b.as_ptr() as *const Unaligned<u32>, b.len() / 4) }
}

fn words_to_bytes(w: &[u32]) -> &[u8] {
    unsafe { slice::from_raw_parts(w.as_ptr() as *const u8, w.len() * 4) }
}
<commit_msg>rustc_metadata: more safely read/write the index positions.<commit_after>use crate::schema::*;

use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
use rustc_serialize::opaque::Encoder;
use std::u32;
use log::debug;

/// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
pub trait FixedSizeEncoding {
    const BYTE_LEN: usize;

    // FIXME(eddyb) convert to and from `[u8; Self::BYTE_LEN]` instead,
    // once that starts being allowed by the compiler (i.e. lazy normalization).
    fn from_bytes(b: &[u8]) -> Self;
    fn write_to_bytes(self, b: &mut [u8]);

    // FIXME(eddyb) make these generic functions, or at least defaults here.
    // (same problem as above, needs `[u8; Self::BYTE_LEN]`)
    // For now, a macro (`fixed_size_encoding_byte_len_and_defaults`) is used.
    fn read_from_bytes_at(b: &[u8], i: usize) -> Self;
    fn write_to_bytes_at(self, b: &mut [u8], i: usize);
}

// HACK(eddyb) this shouldn't be needed (see comments on the methods above).
macro_rules! fixed_size_encoding_byte_len_and_defaults {
    ($byte_len:expr) => {
        const BYTE_LEN: usize = $byte_len;
        fn read_from_bytes_at(b: &[u8], i: usize) -> Self {
            const BYTE_LEN: usize = $byte_len;
            // HACK(eddyb) ideally this would be done with fully safe code,
            // but slicing `[u8]` with `i * N..` is optimized worse, due to the
            // possibility of `i * N` overflowing, than indexing `[[u8; N]]`.
            let b = unsafe {
                std::slice::from_raw_parts(
                    b.as_ptr() as *const [u8; BYTE_LEN],
                    b.len() / BYTE_LEN,
                )
            };
            Self::from_bytes(&b[i])
        }
        fn write_to_bytes_at(self, b: &mut [u8], i: usize) {
            const BYTE_LEN: usize = $byte_len;
            // HACK(eddyb) ideally this would be done with fully safe code,
            // see similar comment in `read_from_bytes_at` for why it can't yet.
            let b = unsafe {
                std::slice::from_raw_parts_mut(
                    b.as_mut_ptr() as *mut [u8; BYTE_LEN],
                    b.len() / BYTE_LEN,
                )
            };
            self.write_to_bytes(&mut b[i]);
        }
    }
}

impl FixedSizeEncoding for u32 {
    fixed_size_encoding_byte_len_and_defaults!(4);

    fn from_bytes(b: &[u8]) -> Self {
        let mut bytes = [0; Self::BYTE_LEN];
        bytes.copy_from_slice(&b[..Self::BYTE_LEN]);
        Self::from_le_bytes(bytes)
    }

    fn write_to_bytes(self, b: &mut [u8]) {
        b[..Self::BYTE_LEN].copy_from_slice(&self.to_le_bytes());
    }
}

/// While we are generating the metadata, we also track the position
/// of each DefIndex. It is not required that all definitions appear
/// in the metadata, nor that they are serialized in order, and
/// therefore we first allocate the vector here and fill it with
/// `u32::MAX`. Whenever an index is visited, we fill in the
/// appropriate spot by calling `record_position`. We should never
/// visit the same index twice.
pub struct Index {
    positions: [Vec<u8>; 2]
}

impl Index {
    pub fn new((max_index_lo, max_index_hi): (usize, usize)) -> Index {
        Index {
            positions: [vec![0xff; max_index_lo * 4],
                        vec![0xff; max_index_hi * 4]],
        }
    }

    pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'_>>) {
        assert!(def_id.is_local());
        self.record_index(def_id.index, entry);
    }

    pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'_>>) {
        assert!(entry.position < (u32::MAX as usize));
        let position = entry.position as u32;
        let space_index = item.address_space().index();
        let array_index = item.as_array_index();

        let positions = &mut self.positions[space_index];
        assert!(u32::read_from_bytes_at(positions, array_index) == u32::MAX,
                "recorded position for item {:?} twice, first at {:?} and now at {:?}",
                item,
                u32::read_from_bytes_at(positions, array_index),
                position);

        position.write_to_bytes_at(positions, array_index)
    }

    pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
        let pos = buf.position();

        // First we write the length of the lower range ...
        buf.emit_raw_bytes(&(self.positions[0].len() as u32 / 4).to_le_bytes());
        // ... then the values in the lower range ...
        buf.emit_raw_bytes(&self.positions[0]);
        // ... then the values in the higher range.
        buf.emit_raw_bytes(&self.positions[1]);
        LazySeq::with_position_and_length(pos as usize,
            (self.positions[0].len() + self.positions[1].len()) / 4 + 1)
    }
}

impl<'tcx> LazySeq<Index> {
    /// Given the metadata, extract out the offset of a particular
    /// DefIndex (if any).
    #[inline(never)]
    pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
        let bytes = &bytes[self.position..];
        debug!("Index::lookup: index={:?} len={:?}",
               def_index,
               self.len);

        let i = def_index.as_array_index() + match def_index.address_space() {
            DefIndexAddressSpace::Low => 0,
            DefIndexAddressSpace::High => {
                // This is a DefIndex in the higher range, so find out where
                // that starts:
                u32::read_from_bytes_at(bytes, 0) as usize
            }
        };

        let position = u32::read_from_bytes_at(bytes, 1 + i);
        if position == u32::MAX {
            debug!("Index::lookup: position=u32::MAX");
            None
        } else {
            debug!("Index::lookup: position={:?}", position);
            Some(Lazy::with_position(position as usize))
        }
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use chrono::{DateTime, Utc};

use std::path::PathBuf;

use devicemapper::Bytes;

use crate::{engine::Filesystem, stratis::StratisResult};

#[derive(Debug)]
pub struct SimFilesystem {
    rand: u32,
    created: DateTime<Utc>,
}

impl SimFilesystem {
    pub fn new() -> SimFilesystem {
        SimFilesystem {
            rand: rand::random::<u32>(),
            created: Utc::now(),
        }
    }
}

impl Filesystem for SimFilesystem {
    fn devnode(&self) -> PathBuf {
        ["/stratis", &format!("random-{}", self.rand)]
            .iter()
            .collect()
    }

    fn created(&self) -> DateTime<Utc> {
        self.created
    }

    fn path_to_mount_filesystem(&self, pool_name: &str, fs_name: &str) -> PathBuf {
        vec!["/somepath", pool_name, fs_name].iter().collect()
    }

    fn used(&self) -> StratisResult<Bytes> {
        Ok(Bytes(12_345_678))
    }
}
<commit_msg>Reorder imports<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::path::PathBuf;

use chrono::{DateTime, Utc};

use devicemapper::Bytes;

use crate::{engine::Filesystem, stratis::StratisResult};

#[derive(Debug)]
pub struct SimFilesystem {
    rand: u32,
    created: DateTime<Utc>,
}

impl SimFilesystem {
    pub fn new() -> SimFilesystem {
        SimFilesystem {
            rand: rand::random::<u32>(),
            created: Utc::now(),
        }
    }
}

impl Filesystem for SimFilesystem {
    fn devnode(&self) -> PathBuf {
        ["/stratis", &format!("random-{}", self.rand)]
            .iter()
            .collect()
    }

    fn created(&self) -> DateTime<Utc> {
        self.created
    }

    fn path_to_mount_filesystem(&self, pool_name: &str, fs_name: &str) -> PathBuf {
        vec!["/somepath", pool_name, fs_name].iter().collect()
    }

    fn used(&self) -> StratisResult<Bytes> {
        Ok(Bytes(12_345_678))
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::AttrBinding;
use dom::bindings::utils::{Reflectable, Reflector, DOMString};
use dom::bindings::utils::reflect_dom_object;
use dom::namespace::{Namespace, Null};
use dom::window::Window;

use std::util;

pub struct Attr {
    reflector_: Reflector,
    local_name: DOMString,
    value: DOMString,
    name: DOMString,
    namespace: Namespace,
    prefix: Option<DOMString>
}

impl Reflectable for Attr {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}

impl Attr {
    fn new_inherited(local_name: DOMString, value: DOMString,
                     name: DOMString, namespace: Namespace,
                     prefix: Option<DOMString>) -> Attr {
        Attr {
            reflector_: Reflector::new(),
            local_name: local_name,
            value: value,
            name: name, //TODO: Intern attribute names
            namespace: namespace,
            prefix: prefix
        }
    }

    pub fn new(window: &Window, local_name: DOMString, value: DOMString) -> @mut Attr {
        let name = local_name.clone();
        Attr::new_helper(window, local_name, value, name, Null, None)
    }

    pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString,
                  name: DOMString, namespace: Namespace,
                  prefix: Option<DOMString>) -> @mut Attr {
        Attr::new_helper(window, name, value, local_name, namespace, prefix)
    }

    fn new_helper(window: &Window, name: DOMString, value: DOMString, local_name: DOMString,
                  namespace: Namespace, prefix: Option<DOMString>) -> @mut Attr {
        let attr = Attr::new_inherited(name, value, local_name, namespace, prefix);
        reflect_dom_object(@mut attr, window, AttrBinding::Wrap)
    }

    pub fn set_value(&mut self, mut value: DOMString) -> DOMString {
        util::swap(&mut self.value, &mut value);
        value
    }
}

impl Attr {
    pub fn LocalName(&self) -> DOMString {
        self.local_name.clone()
    }

    pub fn Value(&self) -> DOMString {
        self.value.clone()
    }

    pub fn SetValue(&mut self, value: DOMString) {
        self.value = value;
    }

    pub fn Name(&self) -> DOMString {
        self.name.clone()
    }

    pub fn GetNamespaceURI(&self) -> Option<DOMString> {
        self.namespace.to_str().map(|s| s.to_owned())
    }

    pub fn GetPrefix(&self) -> Option<DOMString> {
        self.prefix.clone()
    }
}
<commit_msg>auto merge of #1459 : Ms2ger/servo/attr-new, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::AttrBinding;
use dom::bindings::utils::{Reflectable, Reflector, DOMString};
use dom::bindings::utils::reflect_dom_object;
use dom::namespace::{Namespace, Null};
use dom::window::Window;

use std::util;

pub struct Attr {
    reflector_: Reflector,
    local_name: DOMString,
    value: DOMString,
    name: DOMString,
    namespace: Namespace,
    prefix: Option<DOMString>
}

impl Reflectable for Attr {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}

impl Attr {
    fn new_inherited(local_name: DOMString, value: DOMString,
                     name: DOMString, namespace: Namespace,
                     prefix: Option<DOMString>) -> Attr {
        Attr {
            reflector_: Reflector::new(),
            local_name: local_name,
            value: value,
            name: name, //TODO: Intern attribute names
            namespace: namespace,
            prefix: prefix
        }
    }

    pub fn new(window: &Window, local_name: DOMString, value: DOMString) -> @mut Attr {
        let name = local_name.clone();
        Attr::new_helper(window, local_name, value, name, Null, None)
    }

    pub fn new_ns(window: &Window, local_name: DOMString, value: DOMString,
                  name: DOMString, namespace: Namespace,
                  prefix: Option<DOMString>) -> @mut Attr {
        Attr::new_helper(window, local_name, value, name, namespace, prefix)
    }

    fn new_helper(window: &Window, local_name: DOMString, value: DOMString,
                  name: DOMString, namespace: Namespace,
                  prefix: Option<DOMString>) -> @mut Attr {
        let attr = Attr::new_inherited(local_name, value, name, namespace, prefix);
        reflect_dom_object(@mut attr, window, AttrBinding::Wrap)
    }

    pub fn set_value(&mut self, mut value: DOMString) -> DOMString {
        util::swap(&mut self.value, &mut value);
        value
    }
}

impl Attr {
    pub fn LocalName(&self) -> DOMString {
        self.local_name.clone()
    }

    pub fn Value(&self) -> DOMString {
        self.value.clone()
    }

    pub fn SetValue(&mut self, value: DOMString) {
        self.value = value;
    }

    pub fn Name(&self) -> DOMString {
        self.name.clone()
    }

    pub fn GetNamespaceURI(&self) -> Option<DOMString> {
        self.namespace.to_str().map(|s| s.to_owned())
    }

    pub fn GetPrefix(&self) -> Option<DOMString> {
        self.prefix.clone()
    }
}
<|endoftext|>


<commit_before>use columndescription::*;

#[repr(C)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DataType {
    TBIT,
    TBYTE,
    TSBYTE,
    TLOGICAL,
    TSTRING,
    TUSHORT,
    TSHORT,
    TUINT,
    TINT,
    TULONG,
    TLONG,
    TLONGLONG,
    TFLOAT,
    TDOUBLE,
    TCOMPLEX,
    TDBLCOMPLEX,
}

macro_rules! datatype_into_impl {
    ($t: ty) => (
        impl From<DataType> for $t {
            fn from(original: DataType) -> $t {
                match original {
                    DataType::TBIT => 1,
                    DataType::TBYTE => 11,
                    DataType::TSBYTE => 12,
                    DataType::TLOGICAL => 14,
                    DataType::TSTRING => 16,
                    DataType::TUSHORT => 20,
                    DataType::TSHORT => 21,
                    DataType::TUINT => 30,
                    DataType::TINT => 31,
                    DataType::TULONG => 40,
                    DataType::TLONG => 41,
                    DataType::TLONGLONG => 81,
                    DataType::TFLOAT => 42,
                    DataType::TDOUBLE => 82,
                    DataType::TCOMPLEX => 83,
                    DataType::TDBLCOMPLEX => 163,
                }
            }
        }
    )
}

datatype_into_impl!(u8);
datatype_into_impl!(i32);
datatype_into_impl!(u32);
datatype_into_impl!(i64);
datatype_into_impl!(u64);

#[allow(non_camel_case_types)]
#[repr(C)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ImageType {
    BYTE_IMG,
    SHORT_IMG,
    USHORT_IMG,
    LONG_IMG,
    ULONG_IMG,
    LONGLONG_IMG,
    FLOAT_IMG,
    DOUBLE_IMG,
}

macro_rules! imagetype_into_impl {
    ($t: ty) => (
        impl From<ImageType> for $t {
            fn from(original: ImageType) -> $t {
                match original {
                    ImageType::BYTE_IMG => 8,
                    ImageType::SHORT_IMG => 16,
                    ImageType::USHORT_IMG => 20,
                    ImageType::LONG_IMG => 32,
                    ImageType::ULONG_IMG => 40,
                    ImageType::LONGLONG_IMG => 64,
                    ImageType::FLOAT_IMG => -32,
                    ImageType::DOUBLE_IMG => -64,
                }
            }
        }
    )
}

imagetype_into_impl!(i8);
imagetype_into_impl!(i32);
imagetype_into_impl!(i64);

/// Description of the current HDU
///
/// If the current HDU is an image, then
/// [`fetch_hdu_info`](struct.FitsFile.html#method.fetch_hdu_info) returns `HduInfo::ImageInfo`.
/// Otherwise the variant is `HduInfo::TableInfo`.
#[derive(Debug)]
pub enum HduInfo {
    ImageInfo {
        shape: Vec<usize>,
        image_type: ImageType,
    },
    TableInfo {
        column_descriptions: Vec<ConcreteColumnDescription>,
        num_rows: usize,
    },
    AnyInfo,
}

macro_rules! hduinfo_into_impl {
    ($t: ty) => (
        impl From<HduInfo> for $t {
            fn from(original: HduInfo) -> $t {
                match original {
                    HduInfo::ImageInfo { .. } => 0,
                    HduInfo::TableInfo { .. } => 2,
                    HduInfo::AnyInfo => -1,
                }
            }
        }
    )
}

hduinfo_into_impl!(i8);
hduinfo_into_impl!(i32);
hduinfo_into_impl!(i64);

#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
pub enum FileOpenMode {
    READONLY,
    READWRITE,
}

macro_rules! fileopenmode_into_impl {
    ($t: ty) => (
        impl From<FileOpenMode> for $t {
            fn from(original: FileOpenMode) -> $t {
                match original {
                    FileOpenMode::READONLY => 0,
                    FileOpenMode::READWRITE => 1,
                }
            }
        }
        )
}

fileopenmode_into_impl!(u8);
fileopenmode_into_impl!(u32);
fileopenmode_into_impl!(u64);
fileopenmode_into_impl!(i8);
fileopenmode_into_impl!(i32);
fileopenmode_into_impl!(i64);

#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
pub enum CaseSensitivity {
    CASEINSEN,
    CASESEN,
}

macro_rules! casesensitivity_into_impl {
    ($t: ty) => (
        impl From<CaseSensitivity> for $t {
            fn from(original: CaseSensitivity) -> $t {
                match original {
                    CaseSensitivity::CASEINSEN => 0,
                    CaseSensitivity::CASESEN => 1,
                }
            }
        }
        )
}

casesensitivity_into_impl!(u8);
casesensitivity_into_impl!(u32);
casesensitivity_into_impl!(u64);
casesensitivity_into_impl!(i8);
casesensitivity_into_impl!(i32);
casesensitivity_into_impl!(i64);

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

    #[test]
    fn image_types() {
        assert_eq!(i8::from(ImageType::BYTE_IMG), 8);
        assert_eq!(i8::from(ImageType::SHORT_IMG), 16);
        assert_eq!(i8::from(ImageType::USHORT_IMG), 20);
        assert_eq!(i8::from(ImageType::LONG_IMG), 32);
        assert_eq!(i8::from(ImageType::LONGLONG_IMG), 64);
        assert_eq!(i8::from(ImageType::FLOAT_IMG), -32);
        assert_eq!(i8::from(ImageType::DOUBLE_IMG), -64);
    }

    #[test]
    fn hdu_types() {
        let image_info = HduInfo::ImageInfo {
            shape: Vec::new(),
            image_type: ImageType::LONGLONG_IMG,
        };

        let table_info = HduInfo::TableInfo {
            column_descriptions: Vec::new(),
            num_rows: 0,
        };

        assert_eq!(i32::from(image_info), 0);
        assert_eq!(i32::from(table_info), 2);
        assert_eq!(i32::from(HduInfo::AnyInfo), -1);
    }

    #[test]
    fn file_open_modes() {
        assert_eq!(u8::from(FileOpenMode::READONLY), 0);
        assert_eq!(u8::from(FileOpenMode::READWRITE), 1);
    }

    #[test]
    fn case_sensitivity() {
        assert_eq!(u8::from(CaseSensitivity::CASESEN), 1);
        assert_eq!(u8::from(CaseSensitivity::CASEINSEN), 0);
    }

    #[test]
    fn converting_from_data_type() {
        assert_eq!(u8::from(DataType::TBIT), 1);
        assert_eq!(u8::from(DataType::TBYTE), 11);
        assert_eq!(u8::from(DataType::TLOGICAL), 14);
        assert_eq!(u8::from(DataType::TSTRING), 16);
        assert_eq!(u8::from(DataType::TSHORT), 21);
        assert_eq!(u8::from(DataType::TLONG), 41);
        assert_eq!(u8::from(DataType::TFLOAT), 42);
        assert_eq!(u8::from(DataType::TDOUBLE), 82);
    }

}
<commit_msg>BUGFIX: include SBYTE_IMG<commit_after>use columndescription::*;

#[repr(C)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DataType {
    TBIT,
    TBYTE,
    TSBYTE,
    TLOGICAL,
    TSTRING,
    TUSHORT,
    TSHORT,
    TUINT,
    TINT,
    TULONG,
    TLONG,
    TLONGLONG,
    TFLOAT,
    TDOUBLE,
    TCOMPLEX,
    TDBLCOMPLEX,
}

macro_rules! datatype_into_impl {
    ($t: ty) => (
        impl From<DataType> for $t {
            fn from(original: DataType) -> $t {
                match original {
                    DataType::TBIT => 1,
                    DataType::TBYTE => 11,
                    DataType::TSBYTE => 12,
                    DataType::TLOGICAL => 14,
                    DataType::TSTRING => 16,
                    DataType::TUSHORT => 20,
                    DataType::TSHORT => 21,
                    DataType::TUINT => 30,
                    DataType::TINT => 31,
                    DataType::TULONG => 40,
                    DataType::TLONG => 41,
                    DataType::TLONGLONG => 81,
                    DataType::TFLOAT => 42,
                    DataType::TDOUBLE => 82,
                    DataType::TCOMPLEX => 83,
                    DataType::TDBLCOMPLEX => 163,
                }
            }
        }
    )
}

datatype_into_impl!(u8);
datatype_into_impl!(i32);
datatype_into_impl!(u32);
datatype_into_impl!(i64);
datatype_into_impl!(u64);

#[allow(non_camel_case_types)]
#[repr(C)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ImageType {
    BYTE_IMG,
    SBYTE_IMG,
    SHORT_IMG,
    USHORT_IMG,
    LONG_IMG,
    ULONG_IMG,
    LONGLONG_IMG,
    FLOAT_IMG,
    DOUBLE_IMG,
}

macro_rules! imagetype_into_impl {
    ($t: ty) => (
        impl From<ImageType> for $t {
            fn from(original: ImageType) -> $t {
                match original {
                    ImageType::BYTE_IMG => 8,
                    ImageType::SBYTE_IMG => 10,
                    ImageType::SHORT_IMG => 16,
                    ImageType::USHORT_IMG => 20,
                    ImageType::LONG_IMG => 32,
                    ImageType::ULONG_IMG => 40,
                    ImageType::LONGLONG_IMG => 64,
                    ImageType::FLOAT_IMG => -32,
                    ImageType::DOUBLE_IMG => -64,
                }
            }
        }
    )
}

imagetype_into_impl!(i8);
imagetype_into_impl!(i32);
imagetype_into_impl!(i64);

/// Description of the current HDU
///
/// If the current HDU is an image, then
/// [`fetch_hdu_info`](struct.FitsFile.html#method.fetch_hdu_info) returns `HduInfo::ImageInfo`.
/// Otherwise the variant is `HduInfo::TableInfo`.
#[derive(Debug)]
pub enum HduInfo {
    ImageInfo {
        shape: Vec<usize>,
        image_type: ImageType,
    },
    TableInfo {
        column_descriptions: Vec<ConcreteColumnDescription>,
        num_rows: usize,
    },
    AnyInfo,
}

macro_rules! hduinfo_into_impl {
    ($t: ty) => (
        impl From<HduInfo> for $t {
            fn from(original: HduInfo) -> $t {
                match original {
                    HduInfo::ImageInfo { .. } => 0,
                    HduInfo::TableInfo { .. } => 2,
                    HduInfo::AnyInfo => -1,
                }
            }
        }
    )
}

hduinfo_into_impl!(i8);
hduinfo_into_impl!(i32);
hduinfo_into_impl!(i64);

#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
pub enum FileOpenMode {
    READONLY,
    READWRITE,
}

macro_rules! fileopenmode_into_impl {
    ($t: ty) => (
        impl From<FileOpenMode> for $t {
            fn from(original: FileOpenMode) -> $t {
                match original {
                    FileOpenMode::READONLY => 0,
                    FileOpenMode::READWRITE => 1,
                }
            }
        }
        )
}

fileopenmode_into_impl!(u8);
fileopenmode_into_impl!(u32);
fileopenmode_into_impl!(u64);
fileopenmode_into_impl!(i8);
fileopenmode_into_impl!(i32);
fileopenmode_into_impl!(i64);

#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
pub enum CaseSensitivity {
    CASEINSEN,
    CASESEN,
}

macro_rules! casesensitivity_into_impl {
    ($t: ty) => (
        impl From<CaseSensitivity> for $t {
            fn from(original: CaseSensitivity) -> $t {
                match original {
                    CaseSensitivity::CASEINSEN => 0,
                    CaseSensitivity::CASESEN => 1,
                }
            }
        }
        )
}

casesensitivity_into_impl!(u8);
casesensitivity_into_impl!(u32);
casesensitivity_into_impl!(u64);
casesensitivity_into_impl!(i8);
casesensitivity_into_impl!(i32);
casesensitivity_into_impl!(i64);

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

    #[test]
    fn image_types() {
        assert_eq!(i8::from(ImageType::BYTE_IMG), 8);
        assert_eq!(i8::from(ImageType::SBYTE_IMG), 10);
        assert_eq!(i8::from(ImageType::SHORT_IMG), 16);
        assert_eq!(i8::from(ImageType::USHORT_IMG), 20);
        assert_eq!(i8::from(ImageType::LONG_IMG), 32);
        assert_eq!(i8::from(ImageType::LONGLONG_IMG), 64);
        assert_eq!(i8::from(ImageType::FLOAT_IMG), -32);
        assert_eq!(i8::from(ImageType::DOUBLE_IMG), -64);
    }

    #[test]
    fn hdu_types() {
        let image_info = HduInfo::ImageInfo {
            shape: Vec::new(),
            image_type: ImageType::LONGLONG_IMG,
        };

        let table_info = HduInfo::TableInfo {
            column_descriptions: Vec::new(),
            num_rows: 0,
        };

        assert_eq!(i32::from(image_info), 0);
        assert_eq!(i32::from(table_info), 2);
        assert_eq!(i32::from(HduInfo::AnyInfo), -1);
    }

    #[test]
    fn file_open_modes() {
        assert_eq!(u8::from(FileOpenMode::READONLY), 0);
        assert_eq!(u8::from(FileOpenMode::READWRITE), 1);
    }

    #[test]
    fn case_sensitivity() {
        assert_eq!(u8::from(CaseSensitivity::CASESEN), 1);
        assert_eq!(u8::from(CaseSensitivity::CASEINSEN), 0);
    }

    #[test]
    fn converting_from_data_type() {
        assert_eq!(u8::from(DataType::TBIT), 1);
        assert_eq!(u8::from(DataType::TBYTE), 11);
        assert_eq!(u8::from(DataType::TLOGICAL), 14);
        assert_eq!(u8::from(DataType::TSTRING), 16);
        assert_eq!(u8::from(DataType::TSHORT), 21);
        assert_eq!(u8::from(DataType::TLONG), 41);
        assert_eq!(u8::from(DataType::TFLOAT), 42);
        assert_eq!(u8::from(DataType::TDOUBLE), 82);
    }

}
<|endoftext|>