<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;
use core::marker::PhantomData;

use progress::Graph;
use progress::subgraph::Source::ScopeOutput;
use progress::subgraph::Target::ScopeInput;

use communication::exchange::ParallelizationContract;
use example::stream::Stream;
use progress::count_map::CountMap;
use progress::notificator::Notificator;
use progress::{Timestamp, Scope, Antichain};
use communication::channels::{Data, OutputPort, ObserverHelper};
use communication::Pullable;

pub struct PullableHelper<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> {
    receiver:   P,
    consumed:   CountMap<T>,
    phantom:    PhantomData<D>,
}

impl<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> Pullable<(T, Vec<D>)> for PullableHelper<T, D, P> {
    fn pull(&mut self) -> Option<(T, Vec<D>)> {
        if let Some((time, data)) = self.receiver.pull() {
            if data.len() > 0 {
                self.consumed.update(&time, data.len() as i64);
                Some((time, data))
            }
            else { None }
        }
        else { None }
    }
}

impl<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> PullableHelper<T, D, P> {
    pub fn pull_progress(&mut self, consumed: &mut CountMap<T>) {
        while let Some((ref time, value)) = self.consumed.pop() { consumed.update(time, value); }
    }
}

pub trait UnaryExt<G: Graph, D1: Data, D2: Data> {
    fn unary<L: FnMut(&mut UnaryScopeHandle<G::Timestamp, D1, D2, P::Pullable>)+'static,
             P: ParallelizationContract<G::Timestamp, D1>>
            (&mut self, pact: P, name: String, logic: L) -> Stream<G, D2>;
}

impl<G: Graph, D1: Data, D2: Data> UnaryExt<G, D1, D2> for Stream<G, D1> {
    fn unary<L: FnMut(&mut UnaryScopeHandle<G::Timestamp, D1, D2, P::Pullable>)+'static,
             P: ParallelizationContract<G::Timestamp, D1>>
             (&mut self, pact: P, name: String, logic: L) -> Stream<G, D2> {
        let (sender, receiver) = pact.connect(&mut self.graph.communicator());
        let targets = OutputPort::<G::Timestamp,D2>::new();
        let scope = UnaryScope::new(receiver, targets.clone(), name, logic);
        let index = self.graph.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender);
        self.clone_with(ScopeOutput(index, 0), targets)
    }
}

pub struct UnaryScopeHandle<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>> {
    pub input:          PullableHelper<T, D1, P>,
    pub output:         ObserverHelper<OutputPort<T, D2>>,
    pub notificator:    Notificator<T>,
}

pub struct UnaryScope<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>, L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>)> {
    name:           String,
    handle:         UnaryScopeHandle<T, D1, D2, P>,
    logic:          L,
}

impl<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>, L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>)> UnaryScope<T, D1, D2, P, L> {
    pub fn new(receiver: P, targets: OutputPort<T, D2>, name: String, logic: L) -> UnaryScope<T, D1, D2, P, L> {
        UnaryScope {
            name: name,
            handle: UnaryScopeHandle {
                input:       PullableHelper { receiver: receiver, consumed: CountMap::new(), phantom: PhantomData },
                output:      ObserverHelper::new(targets, Rc::new(RefCell::new(CountMap::new()))),
                notificator: Default::default(),
            },
            logic: logic,
        }
    }
}

impl<T, D1, D2, P, L> Scope<T> for UnaryScope<T, D1, D2, P, L>
where T: Timestamp,
      D1: Data, D2: Data,
      P: Pullable<(T, Vec<D1>)>,
      L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>) {
    fn inputs(&self) -> u64 { 1 }
    fn outputs(&self) -> u64 { 1 }

    fn set_external_summary(&mut self, _summaries: Vec<Vec<Antichain<T::Summary>>>, frontier: &mut Vec<CountMap<T>>) -> () {
        self.handle.notificator.update_frontier_from_cm(&mut frontier[0]);
        frontier[0].clear();
    }

    fn push_external_progress(&mut self, external: &mut Vec<CountMap<T>>) -> () {
        self.handle.notificator.update_frontier_from_cm(&mut external[0]);
        external[0].clear();
    }

    fn pull_internal_progress(&mut self, internal: &mut Vec<CountMap<T>>,
                                         consumed: &mut Vec<CountMap<T>>,
                                         produced: &mut Vec<CountMap<T>>) -> bool
    {
        (self.logic)(&mut self.handle);

        // extract what we know about progress from the input and output adapters.
        self.handle.input.pull_progress(&mut consumed[0]);
        self.handle.output.pull_progress(&mut produced[0]);
        self.handle.notificator.pull_progress(&mut internal[0]);

        return false;   // no unannounced internal work
    }

    fn name(&self) -> String { format!("{}", self.name) }
    fn notify_me(&self) -> bool { true }
}
<commit_msg>added constructor for PullableHelper<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;
use core::marker::PhantomData;

use progress::Graph;
use progress::subgraph::Source::ScopeOutput;
use progress::subgraph::Target::ScopeInput;

use communication::exchange::ParallelizationContract;
use example::stream::Stream;
use progress::count_map::CountMap;
use progress::notificator::Notificator;
use progress::{Timestamp, Scope, Antichain};
use communication::channels::{Data, OutputPort, ObserverHelper};
use communication::Pullable;

pub struct PullableHelper<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> {
    receiver:   P,
    consumed:   CountMap<T>,
    phantom:    PhantomData<D>,
}

impl<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> Pullable<(T, Vec<D>)> for PullableHelper<T, D, P> {
    fn pull(&mut self) -> Option<(T, Vec<D>)> {
        if let Some((time, data)) = self.receiver.pull() {
            if data.len() > 0 {
                self.consumed.update(&time, data.len() as i64);
                Some((time, data))
            }
            else { None }
        }
        else { None }
    }
}

impl<T:Timestamp, D:Data, P: Pullable<(T, Vec<D>)>> PullableHelper<T, D, P> {
    pub fn new(input: P) -> PullableHelper<T, D, P> { PullableHelper { receiver: input, consumed: CountMap::new(), phantom: PhantomData }}
    pub fn pull_progress(&mut self, consumed: &mut CountMap<T>) {
        while let Some((ref time, value)) = self.consumed.pop() { consumed.update(time, value); }
    }
}

pub trait UnaryExt<G: Graph, D1: Data, D2: Data> {
    fn unary<L: FnMut(&mut UnaryScopeHandle<G::Timestamp, D1, D2, P::Pullable>)+'static,
             P: ParallelizationContract<G::Timestamp, D1>>
            (&mut self, pact: P, name: String, logic: L) -> Stream<G, D2>;
}

impl<G: Graph, D1: Data, D2: Data> UnaryExt<G, D1, D2> for Stream<G, D1> {
    fn unary<L: FnMut(&mut UnaryScopeHandle<G::Timestamp, D1, D2, P::Pullable>)+'static,
             P: ParallelizationContract<G::Timestamp, D1>>
             (&mut self, pact: P, name: String, logic: L) -> Stream<G, D2> {
        let (sender, receiver) = pact.connect(&mut self.graph.communicator());
        let targets = OutputPort::<G::Timestamp,D2>::new();
        let scope = UnaryScope::new(receiver, targets.clone(), name, logic);
        let index = self.graph.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender);
        self.clone_with(ScopeOutput(index, 0), targets)
    }
}

pub struct UnaryScopeHandle<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>> {
    pub input:          PullableHelper<T, D1, P>,
    pub output:         ObserverHelper<OutputPort<T, D2>>,
    pub notificator:    Notificator<T>,
}

pub struct UnaryScope<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>, L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>)> {
    name:           String,
    handle:         UnaryScopeHandle<T, D1, D2, P>,
    logic:          L,
}

impl<T: Timestamp, D1: Data, D2: Data, P: Pullable<(T, Vec<D1>)>, L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>)> UnaryScope<T, D1, D2, P, L> {
    pub fn new(receiver: P, targets: OutputPort<T, D2>, name: String, logic: L) -> UnaryScope<T, D1, D2, P, L> {
        UnaryScope {
            name: name,
            handle: UnaryScopeHandle {
                input:       PullableHelper::new(receiver),
                output:      ObserverHelper::new(targets, Rc::new(RefCell::new(CountMap::new()))),
                notificator: Default::default(),
            },
            logic: logic,
        }
    }
}

impl<T, D1, D2, P, L> Scope<T> for UnaryScope<T, D1, D2, P, L>
where T: Timestamp,
      D1: Data, D2: Data,
      P: Pullable<(T, Vec<D1>)>,
      L: FnMut(&mut UnaryScopeHandle<T, D1, D2, P>) {
    fn inputs(&self) -> u64 { 1 }
    fn outputs(&self) -> u64 { 1 }

    fn set_external_summary(&mut self, _summaries: Vec<Vec<Antichain<T::Summary>>>, frontier: &mut Vec<CountMap<T>>) -> () {
        self.handle.notificator.update_frontier_from_cm(&mut frontier[0]);
        frontier[0].clear();
    }

    fn push_external_progress(&mut self, external: &mut Vec<CountMap<T>>) -> () {
        self.handle.notificator.update_frontier_from_cm(&mut external[0]);
        external[0].clear();
    }

    fn pull_internal_progress(&mut self, internal: &mut Vec<CountMap<T>>,
                                         consumed: &mut Vec<CountMap<T>>,
                                         produced: &mut Vec<CountMap<T>>) -> bool
    {
        (self.logic)(&mut self.handle);

        // extract what we know about progress from the input and output adapters.
        self.handle.input.pull_progress(&mut consumed[0]);
        self.handle.output.pull_progress(&mut produced[0]);
        self.handle.notificator.pull_progress(&mut internal[0]);

        return false;   // no unannounced internal work
    }

    fn name(&self) -> String { format!("{}", self.name) }
    fn notify_me(&self) -> bool { true }
}
<|endoftext|>


<commit_before>use std;
import vec;
import std::rand;
import option;

// random uint less than n
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }

// random choice from a vec
fn choice<T: copy>(r : rand::rng, v : [T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }

// 1 in n chance of being true
fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }

enum maybe_pointy {
  no_pointy,
  yes_pointy(@pointy),
}

type pointy = {
  mutable x : maybe_pointy,
  mutable y : maybe_pointy,
  mutable z : fn@()->()
};

fn allunder(n: uint, it: block(uint)) {
    let i: uint = 0u;
    while i < n { it(i); i += 1u; }
}

fn nopT(_x : @pointy) { }
fn nop() { }

fn test_cycles(r : rand::rng)
{
    const max : uint = 10u;

    let v : [mutable @pointy] = [mutable];
    allunder(max) {|_i|
        v += [mutable @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() }];
    }

    allunder(max) {|i|
        v[i].x = yes_pointy(v[under(r, max)]);
        v[i].y = yes_pointy(v[under(r, max)]);
        v[i].z = bind nopT(v[under(r, max)]);
    }

    // Drop refs one at a time
    allunder(max) {|i|
        v[i] = @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() };
    }
}

fn main()
{
    let r = rand::mk_rng();
    test_cycles(r);
}
<commit_msg>Improve the cycle-collector fuzzer<commit_after>use std;
import std::rand;
import uint::range;

// random uint less than n
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }

// random choice from a vec
fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }

// k in n chance of being true
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }

const iters : uint = 1000u;
const vlen  : uint = 100u;

enum maybe_pointy {
    none,
    p(@pointy)
}

type pointy = {
    mut a : maybe_pointy,
    mut b : ~maybe_pointy,
    mut c : @maybe_pointy,

    mut f : fn@()->(),
    mut g : fn~()->(),

    mut m : [maybe_pointy],
    mut n : [mut maybe_pointy],
    mut o : {x : int, y : maybe_pointy}
};
// To add: objects; ifaces; anything type-parameterized?

fn empty_pointy() -> @pointy {
    ret @{
        mut a : none,
        mut b : ~none,
        mut c : @none,

        mut f : fn@()->(){},
        mut g : fn~()->(){},

        mut m : [],
        mut n : [mut],
        mut o : {x : 0, y : none}
    }
}

fn nopP(_x : @pointy) { }
fn nop<T>(_x: T) { }

fn test_cycles(r : rand::rng, k: uint, n: uint)
{
    let v : [mut @pointy] = [mut];

    // Create a graph with no edges
    range(0u, vlen) {|_i|
        v += [mut empty_pointy()];
    }

    // Fill in the graph with random edges, with density k/n
    range(0u, vlen) {|i|
        if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }

        if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
        if (false)               { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
          // https://github.com/mozilla/rust/issues/1899

        if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
    }

    // Drop refs one at a time
    range(0u, vlen) {|i|
        v[i] = empty_pointy()
    }
}

fn main()
{
    let r = rand::mk_rng();
    range(0u, iters) {|i|
        test_cycles(r, i, iters);
    }
}
<|endoftext|>


<commit_before>mod terminal;
mod ansi;

use std::io::{self, Write, BufWriter};
use self::terminal::{Terminal, Event, Key};
use self::ansi::{clear, color, cursor, style};
use rayon::prelude::*;
use rff::choice::Choice;

#[derive(Debug)]
pub enum Error {
    Exit,
    Write(io::Error),
    Reset(terminal::Error)
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Write(err)
    }
}

impl From<terminal::Error> for Error {
    fn from(err: terminal::Error) -> Error {
        Error::Reset(err)
    }
}

pub struct Options {
    pub choices: Vec<String>,
    pub initial: String,
}

pub struct Interface {
    choices: Vec<String>,
    matches: Vec<Choice>,
    choices_width: usize,
    selected: usize,
    search: String,
    width: usize,
    terminal: Terminal,
}

impl Interface {
    /// Creates a new Interface from the provided options.
    pub fn from_opts(opts: Options) -> Interface {
        let mut term = Terminal::from("/dev/tty").unwrap();
        term.set_raw_mode().unwrap();

        let choices_width = format!("{}", opts.choices.len()).len();

        Interface {
            choices: opts.choices,
            matches: Vec::new(),
            choices_width: choices_width,
            selected: 0,
            search: opts.initial,
            width: term.max_width,
            terminal: term
        }
    }

    // Starts the interface
    pub fn run(&mut self) -> Result<&str, Error> {
        self.filter_choices();
        self.render()?;

        for event in self.terminal.events()? {
            if let Event::Key(key) = event? {
                match key {
                    Key::Ctrl('c') | Key::Ctrl('d') => {
                        self.clear()?;
                        return Err(Error::Exit);
                    }

                    Key::Char('\n') => {
                        break;
                    },

                    Key::Ctrl('n') => {
                        self.selected += 1;
                        self.clamp_selected();
                        self.render()?;
                    },

                    Key::Ctrl('p') => {
                        self.selected = self.selected.
                            checked_sub(1).
                            unwrap_or(0);

                        self.clamp_selected();
                        self.render()?;
                    },

                    Key::Char(ch) => {
                        self.search.push(ch);
                        self.filter_existing_matches();
                        self.render()?;
                    },

                    Key::Backspace | Key::Ctrl('h') => {
                        self.search.pop();
                        self.filter_choices();
                        self.render()?;
                    }

                    Key::Ctrl('u') => {
                        self.search.clear();
                        self.filter_choices();
                        self.render()?;
                    }

                    _ => {}
                }
            };
        }

        self.clear()?;
        Ok(self.result())
    }

    fn filter_choices(&mut self) {
        let mut matches = self.choices.
            par_iter().
            cloned().
            filter_map(|choice| Choice::with_positions(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(a).unwrap());

        self.matches = matches;
    }

    fn filter_existing_matches(&mut self) {
        let mut matches = self.matches.
            par_iter().
            map(|c| c.text().to_string()).
            filter_map(|choice| Choice::with_positions(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(a).unwrap());

        self.matches = matches;
    }

    fn prompt(&self) -> String {
        let count = self.matches.len();
        format!("{:width$} > {}", count, self.search, width = self.choices_width)
    }

    fn render(&mut self) -> io::Result<()> {
        let prompt = self.prompt();
        let matches = self.matches.iter().take(10);
        let n = matches.len() as u16;

        let mut term = BufWriter::new(&mut self.terminal);

        write!(term, "{}{}{}", cursor::Column(1), clear::Screen, prompt)?;

        for (i, choice) in matches.enumerate() {
            write!(term, "\r\n")?;

            let selected = i == self.selected;

            if selected {
                write!(term, "{}", style::Invert)?;
                print_choice(&mut term, choice, self.width)?;
                write!(term, "{}", style::NoInvert)?;
            } else {
                print_choice(&mut term, choice, self.width)?;
            }
        }

        if n > 0 {
            let col = (prompt.len() + 1) as u16;
            write!(term, "{}{}", cursor::Up(n), cursor::Column(col))?;
        }

        Ok(())
    }

    #[inline(always)]
    fn clamp_selected(&mut self) {
        let mut max = self.matches.len();
        if max > 10 { max = 10; }

        if self.selected >= max {
            self.selected = max - 1;
        }
    }

    fn clear(&mut self) -> Result<(), Error> {
        write!(self.terminal, "{}{}", cursor::Column(1), clear::Screen)?;
        self.terminal.reset()?;
        Ok(())
    }

    fn result(&mut self) -> &str {
        self.matches.iter().
            map(|c| c.text()).
            nth(self.selected).
            unwrap_or(&self.search)
    }
}

fn print_choice(term: &mut BufWriter<&mut Terminal>, choice: &Choice, max_width: usize) -> io::Result<()> {
    let chars = choice.text().chars().take(max_width);

    if let Some(positions) = choice.positions() {
        for (i, ch) in chars.enumerate() {
            let is_match = positions.iter().any(|p| *p == i);

            if is_match {
                let color = color::Fg(color::Colors::Magenta);
                let reset = color::Fg(color::Reset);
                write!(term, "{}{}{}", color, ch, reset)?;
            } else {
                write!(term, "{}", ch)?;
            }
        }
    } else {
        write!(term, "{}", chars.collect::<String>())?;
    }

    Ok(())
}
<commit_msg>Move choice rendering back inline<commit_after>mod terminal;
mod ansi;

use std::io::{self, Write, BufWriter};
use self::terminal::{Terminal, Event, Key};
use self::ansi::{clear, color, cursor, style};
use rayon::prelude::*;
use rff::choice::Choice;

#[derive(Debug)]
pub enum Error {
    Exit,
    Write(io::Error),
    Reset(terminal::Error)
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Write(err)
    }
}

impl From<terminal::Error> for Error {
    fn from(err: terminal::Error) -> Error {
        Error::Reset(err)
    }
}

pub struct Options {
    pub choices: Vec<String>,
    pub initial: String,
}

pub struct Interface {
    choices: Vec<String>,
    matches: Vec<Choice>,
    choices_width: usize,
    selected: usize,
    search: String,
    width: usize,
    terminal: Terminal,
}

impl Interface {
    /// Creates a new Interface from the provided options.
    pub fn from_opts(opts: Options) -> Interface {
        let mut term = Terminal::from("/dev/tty").unwrap();
        term.set_raw_mode().unwrap();

        let choices_width = format!("{}", opts.choices.len()).len();

        Interface {
            choices: opts.choices,
            matches: Vec::new(),
            choices_width: choices_width,
            selected: 0,
            search: opts.initial,
            width: term.max_width,
            terminal: term
        }
    }

    // Starts the interface
    pub fn run(&mut self) -> Result<&str, Error> {
        self.filter_choices();
        self.render()?;

        for event in self.terminal.events()? {
            if let Event::Key(key) = event? {
                match key {
                    Key::Ctrl('c') | Key::Ctrl('d') => {
                        self.clear()?;
                        return Err(Error::Exit);
                    }

                    Key::Char('\n') => {
                        break;
                    },

                    Key::Ctrl('n') => {
                        self.selected += 1;
                        self.clamp_selected();
                        self.render()?;
                    },

                    Key::Ctrl('p') => {
                        self.selected = self.selected.
                            checked_sub(1).
                            unwrap_or(0);

                        self.clamp_selected();
                        self.render()?;
                    },

                    Key::Char(ch) => {
                        self.search.push(ch);
                        self.filter_existing_matches();
                        self.render()?;
                    },

                    Key::Backspace | Key::Ctrl('h') => {
                        self.search.pop();
                        self.filter_choices();
                        self.render()?;
                    }

                    Key::Ctrl('u') => {
                        self.search.clear();
                        self.filter_choices();
                        self.render()?;
                    }

                    _ => {}
                }
            };
        }

        self.clear()?;
        Ok(self.result())
    }

    fn filter_choices(&mut self) {
        let mut matches = self.choices.
            par_iter().
            cloned().
            filter_map(|choice| Choice::with_positions(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(a).unwrap());

        self.matches = matches;
    }

    fn filter_existing_matches(&mut self) {
        let mut matches = self.matches.
            par_iter().
            map(|c| c.text().to_string()).
            filter_map(|choice| Choice::with_positions(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(a).unwrap());

        self.matches = matches;
    }

    fn prompt(&self) -> String {
        let count = self.matches.len();
        format!("{:width$} > {}", count, self.search, width = self.choices_width)
    }

    fn render(&mut self) -> io::Result<()> {
        let prompt = self.prompt();
        let matches = self.matches.iter().take(10);
        let n = matches.len() as u16;

        let mut term = BufWriter::new(&mut self.terminal);

        write!(term, "{}{}{}", cursor::Column(1), clear::Screen, prompt)?;

        for (i, choice) in matches.enumerate() {
            let selected = i == self.selected;
            let chars = choice.text().chars().take(self.width);

            write!(term, "\r\n")?;

            if selected {
                write!(term, "{}", style::Invert)?;
            }

            if let Some(positions) = choice.positions() {
                for (i, ch) in chars.enumerate() {
                    let is_match = positions.iter().any(|p| *p == i);

                    if is_match {
                        let color = color::Fg(color::Colors::Magenta);
                        let reset = color::Fg(color::Reset);
                        write!(term, "{}{}{}", color, ch, reset)?;
                    } else {
                        write!(term, "{}", ch)?;
                    }
                }
            } else {
                write!(term, "{}", chars.collect::<String>())?;
            }

            if selected {
                write!(term, "{}", style::NoInvert)?;
            }
        }

        if n > 0 {
            let col = (prompt.len() + 1) as u16;
            write!(term, "{}{}", cursor::Up(n), cursor::Column(col))?;
        }

        Ok(())
    }

    #[inline(always)]
    fn clamp_selected(&mut self) {
        let mut max = self.matches.len();
        if max > 10 { max = 10; }

        if self.selected >= max {
            self.selected = max - 1;
        }
    }

    fn clear(&mut self) -> Result<(), Error> {
        write!(self.terminal, "{}{}", cursor::Column(1), clear::Screen)?;
        self.terminal.reset()?;
        Ok(())
    }

    fn result(&mut self) -> &str {
        self.matches.iter().
            map(|c| c.text()).
            nth(self.selected).
            unwrap_or(&self.search)
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

//! The `Clone` trait for types that cannot be 'implicitly copied'
//!
//! In Rust, some simple types are "implicitly copyable" and when you
//! assign them or pass them as arguments, the receiver will get a copy,
//! leaving the original value in place. These types do not require
//! allocation to copy and do not have finalizers (i.e. they do not
//! contain owned boxes or implement `Drop`), so the compiler considers
//! them cheap and safe to copy. For other types copies must be made
//! explicitly, by convention implementing the `Clone` trait and calling
//! the `clone` method.

#![stable]

use kinds::Sized;

/// A common trait for cloning an object.
#[stable]
pub trait Clone {
    /// Returns a copy of the value.
    #[stable]
    fn clone(&self) -> Self;

    /// Perform copy-assignment from `source`.
    ///
    /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
    /// but can be overridden to reuse the resources of `a` to avoid unnecessary
    /// allocations.
    #[inline(always)]
    #[unstable = "this function rarely unused"]
    fn clone_from(&mut self, source: &Self) {
        *self = source.clone()
    }
}

#[stable]
impl<'a, Sized? T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}

macro_rules! clone_impl {
    ($t:ty) => {
        #[stable]
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline]
            fn clone(&self) -> $t { *self }
        }
    }
}

clone_impl! { int }
clone_impl! { i8 }
clone_impl! { i16 }
clone_impl! { i32 }
clone_impl! { i64 }

clone_impl! { uint }
clone_impl! { u8 }
clone_impl! { u16 }
clone_impl! { u32 }
clone_impl! { u64 }

clone_impl! { f32 }
clone_impl! { f64 }

clone_impl! { () }
clone_impl! { bool }
clone_impl! { char }

macro_rules! extern_fn_clone {
    ($($A:ident),*) => (
        #[experimental = "this may not be sufficient for fns with region parameters"]
        impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
            /// Return a copy of a function pointer
            #[inline]
            fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
        }
    )
}

extern_fn_clone! {}
extern_fn_clone! { A }
extern_fn_clone! { A, B }
extern_fn_clone! { A, B, C }
extern_fn_clone! { A, B, C, D }
extern_fn_clone! { A, B, C, D, E }
extern_fn_clone! { A, B, C, D, E, F }
extern_fn_clone! { A, B, C, D, E, F, G }
extern_fn_clone! { A, B, C, D, E, F, G, H }
<commit_msg>Fix a typo<commit_after>// Copyright 2012-2013 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.

//! The `Clone` trait for types that cannot be 'implicitly copied'
//!
//! In Rust, some simple types are "implicitly copyable" and when you
//! assign them or pass them as arguments, the receiver will get a copy,
//! leaving the original value in place. These types do not require
//! allocation to copy and do not have finalizers (i.e. they do not
//! contain owned boxes or implement `Drop`), so the compiler considers
//! them cheap and safe to copy. For other types copies must be made
//! explicitly, by convention implementing the `Clone` trait and calling
//! the `clone` method.

#![stable]

use kinds::Sized;

/// A common trait for cloning an object.
#[stable]
pub trait Clone {
    /// Returns a copy of the value.
    #[stable]
    fn clone(&self) -> Self;

    /// Perform copy-assignment from `source`.
    ///
    /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
    /// but can be overridden to reuse the resources of `a` to avoid unnecessary
    /// allocations.
    #[inline(always)]
    #[unstable = "this function is rarely used"]
    fn clone_from(&mut self, source: &Self) {
        *self = source.clone()
    }
}

#[stable]
impl<'a, Sized? T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}

macro_rules! clone_impl {
    ($t:ty) => {
        #[stable]
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline]
            fn clone(&self) -> $t { *self }
        }
    }
}

clone_impl! { int }
clone_impl! { i8 }
clone_impl! { i16 }
clone_impl! { i32 }
clone_impl! { i64 }

clone_impl! { uint }
clone_impl! { u8 }
clone_impl! { u16 }
clone_impl! { u32 }
clone_impl! { u64 }

clone_impl! { f32 }
clone_impl! { f64 }

clone_impl! { () }
clone_impl! { bool }
clone_impl! { char }

macro_rules! extern_fn_clone {
    ($($A:ident),*) => (
        #[experimental = "this may not be sufficient for fns with region parameters"]
        impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
            /// Return a copy of a function pointer
            #[inline]
            fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
        }
    )
}

extern_fn_clone! {}
extern_fn_clone! { A }
extern_fn_clone! { A, B }
extern_fn_clone! { A, B, C }
extern_fn_clone! { A, B, C, D }
extern_fn_clone! { A, B, C, D, E }
extern_fn_clone! { A, B, C, D, E, F }
extern_fn_clone! { A, B, C, D, E, F, G }
extern_fn_clone! { A, B, C, D, E, F, G, H }
<|endoftext|>


<commit_before>// Copyright 2012 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.

//! Operations on tuples
//!
//! To access a single element of a tuple one can use the following
//! methods:
//!
//! * `valN` - returns a value of _N_-th element
//! * `refN` - returns a reference to _N_-th element
//! * `mutN` - returns a mutable reference to _N_-th element
//!
//! Indexing starts from zero, so `val0` returns first value, `val1`
//! returns second value, and so on. In general, a tuple with _S_
//! elements provides aforementioned methods suffixed with numbers
//! from `0` to `S-1`. Traits which contain these methods are
//! implemented for tuples with up to 12 elements.
//!
//! If every type inside a tuple implements one of the following
//! traits, then a tuple itself also implements it.
//!
//! * `Clone`
//! * `PartialEq`
//! * `Eq`
//! * `PartialOrd`
//! * `Ord`
//! * `Default`

#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "tuple")]

use clone::Clone;
use cmp::*;
use cmp::Ordering::*;
use default::Default;
use option::Option;
use option::Option::Some;

// FIXME(#19630) Remove this work-around
macro_rules! e {
    ($e:expr) => { $e }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
    ($(
        $Tuple:ident {
            $(($idx:tt) -> $T:ident)+
        }
    )+) => {
        $(
            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Clone),+> Clone for ($($T,)+) {
                fn clone(&self) -> ($($T,)+) {
                    ($(e!(self.$idx.clone()),)+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
                #[inline]
                fn eq(&self, other: &($($T,)+)) -> bool {
                    e!($(self.$idx == other.$idx)&&+)
                }
                #[inline]
                fn ne(&self, other: &($($T,)+)) -> bool {
                    e!($(self.$idx != other.$idx)||+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Eq),+> Eq for ($($T,)+) {}

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
                #[inline]
                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
                    lexical_partial_cmp!($(self.$idx, other.$idx),+)
                }
                #[inline]
                fn lt(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(lt, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn le(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(le, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn ge(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(ge, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn gt(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(gt, $(self.$idx, other.$idx),+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Ord),+> Ord for ($($T,)+) {
                #[inline]
                fn cmp(&self, other: &($($T,)+)) -> Ordering {
                    lexical_cmp!($(self.$idx, other.$idx),+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Default),+> Default for ($($T,)+) {
                #[stable(feature = "rust1", since = "1.0.0")]
                #[inline]
                fn default() -> ($($T,)+) {
                    ($({ let x: $T = Default::default(); x},)+)
                }
            }
        )+
    }
}

// Constructs an expression that performs a lexical ordering using method $rel.
// The values are interleaved, so the macro invocation for
// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
// a3, b3)` (and similarly for `lexical_cmp`)
macro_rules! lexical_ord {
    ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        if $a != $b { lexical_ord!($rel, $a, $b) }
        else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
    };
    ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
}

macro_rules! lexical_partial_cmp {
    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        match ($a).partial_cmp(&$b) {
            Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
            ordering   => ordering
        }
    };
    ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
}

macro_rules! lexical_cmp {
    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        match ($a).cmp(&$b) {
            Equal => lexical_cmp!($($rest_a, $rest_b),+),
            ordering   => ordering
        }
    };
    ($a:expr, $b:expr) => { ($a).cmp(&$b) };
}

tuple_impls! {
    Tuple1 {
        (0) -> A
    }
    Tuple2 {
        (0) -> A
        (1) -> B
    }
    Tuple3 {
        (0) -> A
        (1) -> B
        (2) -> C
    }
    Tuple4 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
    }
    Tuple5 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
    }
    Tuple6 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
    }
    Tuple7 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
    }
    Tuple8 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
    }
    Tuple9 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
    }
    Tuple10 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
    }
    Tuple11 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
        (10) -> K
    }
    Tuple12 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
        (10) -> K
        (11) -> L
    }
}
<commit_msg>core: Update tuple doc<commit_after>// Copyright 2012 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.

//! Operations on tuples
//!
//! To access a single element of a tuple one can use the `.0`
//! field access syntax.
//!
//! Indexing starts from zero, so `.0` returns first value, `.1`
//! returns second value, and so on. In general, a tuple with *N*
//! elements has field accessors from 0 to *N* - 1.
//!
//! If every type inside a tuple implements one of the following
//! traits, then a tuple itself also implements it.
//!
//! * `Clone`
//! * `PartialEq`
//! * `Eq`
//! * `PartialOrd`
//! * `Ord`
//! * `Default`

#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "tuple")]

use clone::Clone;
use cmp::*;
use cmp::Ordering::*;
use default::Default;
use option::Option;
use option::Option::Some;

// FIXME(#19630) Remove this work-around
macro_rules! e {
    ($e:expr) => { $e }
}

// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
    ($(
        $Tuple:ident {
            $(($idx:tt) -> $T:ident)+
        }
    )+) => {
        $(
            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Clone),+> Clone for ($($T,)+) {
                fn clone(&self) -> ($($T,)+) {
                    ($(e!(self.$idx.clone()),)+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
                #[inline]
                fn eq(&self, other: &($($T,)+)) -> bool {
                    e!($(self.$idx == other.$idx)&&+)
                }
                #[inline]
                fn ne(&self, other: &($($T,)+)) -> bool {
                    e!($(self.$idx != other.$idx)||+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Eq),+> Eq for ($($T,)+) {}

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
                #[inline]
                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
                    lexical_partial_cmp!($(self.$idx, other.$idx),+)
                }
                #[inline]
                fn lt(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(lt, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn le(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(le, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn ge(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(ge, $(self.$idx, other.$idx),+)
                }
                #[inline]
                fn gt(&self, other: &($($T,)+)) -> bool {
                    lexical_ord!(gt, $(self.$idx, other.$idx),+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Ord),+> Ord for ($($T,)+) {
                #[inline]
                fn cmp(&self, other: &($($T,)+)) -> Ordering {
                    lexical_cmp!($(self.$idx, other.$idx),+)
                }
            }

            #[stable(feature = "rust1", since = "1.0.0")]
            impl<$($T:Default),+> Default for ($($T,)+) {
                #[stable(feature = "rust1", since = "1.0.0")]
                #[inline]
                fn default() -> ($($T,)+) {
                    ($({ let x: $T = Default::default(); x},)+)
                }
            }
        )+
    }
}

// Constructs an expression that performs a lexical ordering using method $rel.
// The values are interleaved, so the macro invocation for
// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
// a3, b3)` (and similarly for `lexical_cmp`)
macro_rules! lexical_ord {
    ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        if $a != $b { lexical_ord!($rel, $a, $b) }
        else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
    };
    ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
}

macro_rules! lexical_partial_cmp {
    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        match ($a).partial_cmp(&$b) {
            Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
            ordering   => ordering
        }
    };
    ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
}

macro_rules! lexical_cmp {
    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
        match ($a).cmp(&$b) {
            Equal => lexical_cmp!($($rest_a, $rest_b),+),
            ordering   => ordering
        }
    };
    ($a:expr, $b:expr) => { ($a).cmp(&$b) };
}

tuple_impls! {
    Tuple1 {
        (0) -> A
    }
    Tuple2 {
        (0) -> A
        (1) -> B
    }
    Tuple3 {
        (0) -> A
        (1) -> B
        (2) -> C
    }
    Tuple4 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
    }
    Tuple5 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
    }
    Tuple6 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
    }
    Tuple7 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
    }
    Tuple8 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
    }
    Tuple9 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
    }
    Tuple10 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
    }
    Tuple11 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
        (10) -> K
    }
    Tuple12 {
        (0) -> A
        (1) -> B
        (2) -> C
        (3) -> D
        (4) -> E
        (5) -> F
        (6) -> G
        (7) -> H
        (8) -> I
        (9) -> J
        (10) -> K
        (11) -> L
    }
}
<|endoftext|>


<commit_before>use database::models::{ToU64, LogChannel};

use chrono::{Utc, Duration};

use diesel::prelude::*;

use serenity::prelude::{Mutex, Mentionable};
use serenity::client::{Context, EventHandler};
use serenity::model::channel::Message;
use serenity::model::event::MessageUpdateEvent;
use serenity::model::guild::{Member, Action};
use serenity::model::id::{GuildId, ChannelId, UserId, MessageId};
use serenity::model::user::User;

use std::collections::HashMap;
use std::sync::atomic::{Ordering, AtomicUsize};
use std::thread;

macro_rules! update_message {
  ($message:expr, $update:expr, $($field:ident),+) => {{
    $(
      if let Some(f) = $update.$field {
        $message.$field = f;
      }
    )+
  }}
}

#[derive(Default)]
pub struct Log {
  messages: Mutex<HashMap<UserId, HashMap<GuildId, Vec<Message>>>>,
  count: AtomicUsize
}

impl Log {
  fn get_log_channel<G: Into<GuildId>>(&self, guild: G) -> Option<ChannelId> {
    let guild = guild.into().to_u64();
    let log_channel: Option<LogChannel> = ::bot::with_connection(|c| {
      use database::schema::log_channels::dsl;
      dsl::log_channels.filter(dsl::server_id.eq(guild)).first(c)
    }).ok();
    log_channel.map(|x| ChannelId(*x.channel_id))
  }

  fn prune_messages(&self) {
    let now = Utc::now();
    let one_day = Duration::days(1);
    self.messages
      .lock()
      .values_mut()
      .flat_map(|x| x.values_mut())
      .for_each(|x| x.retain(|m| m.timestamp.signed_duration_since(now) < one_day));
  }
}

impl EventHandler for Log {
  fn guild_member_removal(&self, _: Context, guild: GuildId, user: User, member: Option<Member>) {
    let channel_id = some_or!(self.get_log_channel(guild), return);
    let mention = member.as_ref().map(|x| x.mention()).unwrap_or_else(|| user.mention());
    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&user.tag())
          .icon_url(&user.face()));
      if let Some(member) = member {
        embed = embed.field("Display name", member.display_name(), true);
      }
      embed = embed
        .field("Mention", mention, true)
        .field("Action", "Leave server", true)
        .timestamp(&Utc::now())
        .footer(|f| f.text(user.id));
      embed
    })).ok();
  }

  fn guild_member_addition(&self, _: Context, guild: GuildId, member: Member) {
    let channel_id = some_or!(self.get_log_channel(guild), return);
    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&member.user.read().tag())
          .icon_url(&member.user.read().face()));
      embed = embed
        .field("Mention", member.mention(), true)
        .field("Action", "Join server", true)
        .timestamp(&Utc::now())
        .footer(|f| f.text(member.user.read().id));
      embed
    })).ok();
  }

  fn message_update(&self, _: Context, update: MessageUpdateEvent) {
    let author = match update.author {
      Some(ref a) => a,
      None => return
    };
    let new_content = match update.content {
      Some(ref c) => c,
      None => return
    };

    let channel = match update.channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", update.channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };
    let reader = guild_channel.read();

    let channel_id = some_or!(self.get_log_channel(reader.guild_id), return);

    let guild = match reader.guild_id.find() {
      Some(g) => g,
      None => return
    };
    let guild_reader = guild.read();

    let member = match guild_reader.members.get(&author.id).cloned().or_else(|| guild_reader.member(author.id).ok()) {
      Some(m) => m,
      None => return
    };

    let mut messages = self.messages.lock();
    let message = messages
      .get_mut(&author.id)
      .and_then(|x| x.get_mut(&reader.guild_id))
      .and_then(|x| x.iter_mut().find(|m| m.id == update.id));
    let message = match message {
      Some(m) => m,
      None => return
    };

    let original_content = message.content.clone();
    let channel_mention = update.channel_id.mention();
    let message_id = update.id;

    update_message!(
      message,
      update,
      kind, content, tts, pinned, timestamp, author, mention_everyone, mentions, mention_roles,
      attachments
    );
    message.edited_timestamp = update.edited_timestamp;

    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&member.user.read().tag())
          .icon_url(&member.user.read().face()));
      embed = embed
        .field("Mention", member.mention(), true)
        .field("Action", "Edited message", true)
        .field("Channel", channel_mention, true)
        .field("Original message", original_content, false)
        .field("New message", new_content, false)
        .timestamp(&Utc::now())
        .footer(|f| f.text(message_id));
      embed
    })).ok();
  }

  fn message_delete(&self, _: Context, channel_id: ChannelId, message_id: MessageId) {
    let channel = match channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };
    let reader = guild_channel.read();

    let log_channel = some_or!(self.get_log_channel(reader.guild_id), return);

    let guild = match reader.guild_id.find() {
      Some(g) => g,
      None => return
    };

    let guild_reader = guild.read();

    let mut messages = self.messages.lock();
    let message = messages
      .values_mut()
      .filter_map(|x| x.get_mut(&reader.guild_id))
      .next()
      .and_then(|x| x.iter_mut().find(|m| m.id == message_id));
    let message = match message {
      Some(m) => m.clone(),
      None => return
    };

    let deletee = some_or!(guild_reader.members.get(&message.author.id).cloned().or_else(|| guild_reader.member(message.author.id).ok()), return);

    let original_content = message.content;
    let channel_mention = channel_id.mention();

    log_channel.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&deletee.user.read().tag())
          .icon_url(&deletee.user.read().face()));
      embed = embed
        .field("Mention", deletee.mention(), true)
        .field("Action", "Had message deleted", true)
        .field("Channel", channel_mention, true)
        .field("Content", original_content, false)
        .timestamp(&Utc::now())
        .footer(|f| f.text(message_id));
      embed
    })).ok();
  }

  fn message(&self, _: Context, message: Message) {
    if self.count.load(Ordering::SeqCst) == 100 {
      self.count.store(0, Ordering::SeqCst);

      self.prune_messages();
    }

    let channel = match message.channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", message.channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };

    let reader = guild_channel.read();

    self.messages
      .lock()
      .entry(message.author.id)
      .or_default()
      .entry(reader.guild_id)
      .or_default()
      .push(message);

    self.count.fetch_add(1, Ordering::SeqCst);
  }
}
<commit_msg>style: remove unused imports<commit_after>use database::models::{ToU64, LogChannel};

use chrono::{Utc, Duration};

use diesel::prelude::*;

use serenity::prelude::{Mutex, Mentionable};
use serenity::client::{Context, EventHandler};
use serenity::model::channel::Message;
use serenity::model::event::MessageUpdateEvent;
use serenity::model::guild::Member;
use serenity::model::id::{GuildId, ChannelId, UserId, MessageId};
use serenity::model::user::User;

use std::collections::HashMap;
use std::sync::atomic::{Ordering, AtomicUsize};

macro_rules! update_message {
  ($message:expr, $update:expr, $($field:ident),+) => {{
    $(
      if let Some(f) = $update.$field {
        $message.$field = f;
      }
    )+
  }}
}

#[derive(Default)]
pub struct Log {
  messages: Mutex<HashMap<UserId, HashMap<GuildId, Vec<Message>>>>,
  count: AtomicUsize
}

impl Log {
  fn get_log_channel<G: Into<GuildId>>(&self, guild: G) -> Option<ChannelId> {
    let guild = guild.into().to_u64();
    let log_channel: Option<LogChannel> = ::bot::with_connection(|c| {
      use database::schema::log_channels::dsl;
      dsl::log_channels.filter(dsl::server_id.eq(guild)).first(c)
    }).ok();
    log_channel.map(|x| ChannelId(*x.channel_id))
  }

  fn prune_messages(&self) {
    let now = Utc::now();
    let one_day = Duration::days(1);
    self.messages
      .lock()
      .values_mut()
      .flat_map(|x| x.values_mut())
      .for_each(|x| x.retain(|m| m.timestamp.signed_duration_since(now) < one_day));
  }
}

impl EventHandler for Log {
  fn guild_member_removal(&self, _: Context, guild: GuildId, user: User, member: Option<Member>) {
    let channel_id = some_or!(self.get_log_channel(guild), return);
    let mention = member.as_ref().map(|x| x.mention()).unwrap_or_else(|| user.mention());
    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&user.tag())
          .icon_url(&user.face()));
      if let Some(member) = member {
        embed = embed.field("Display name", member.display_name(), true);
      }
      embed = embed
        .field("Mention", mention, true)
        .field("Action", "Leave server", true)
        .timestamp(&Utc::now())
        .footer(|f| f.text(user.id));
      embed
    })).ok();
  }

  fn guild_member_addition(&self, _: Context, guild: GuildId, member: Member) {
    let channel_id = some_or!(self.get_log_channel(guild), return);
    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&member.user.read().tag())
          .icon_url(&member.user.read().face()));
      embed = embed
        .field("Mention", member.mention(), true)
        .field("Action", "Join server", true)
        .timestamp(&Utc::now())
        .footer(|f| f.text(member.user.read().id));
      embed
    })).ok();
  }

  fn message_update(&self, _: Context, update: MessageUpdateEvent) {
    let author = match update.author {
      Some(ref a) => a,
      None => return
    };
    let new_content = match update.content {
      Some(ref c) => c,
      None => return
    };

    let channel = match update.channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", update.channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };
    let reader = guild_channel.read();

    let channel_id = some_or!(self.get_log_channel(reader.guild_id), return);

    let guild = match reader.guild_id.find() {
      Some(g) => g,
      None => return
    };
    let guild_reader = guild.read();

    let member = match guild_reader.members.get(&author.id).cloned().or_else(|| guild_reader.member(author.id).ok()) {
      Some(m) => m,
      None => return
    };

    let mut messages = self.messages.lock();
    let message = messages
      .get_mut(&author.id)
      .and_then(|x| x.get_mut(&reader.guild_id))
      .and_then(|x| x.iter_mut().find(|m| m.id == update.id));
    let message = match message {
      Some(m) => m,
      None => return
    };

    let original_content = message.content.clone();
    let channel_mention = update.channel_id.mention();
    let message_id = update.id;

    update_message!(
      message,
      update,
      kind, content, tts, pinned, timestamp, author, mention_everyone, mentions, mention_roles,
      attachments
    );
    message.edited_timestamp = update.edited_timestamp;

    channel_id.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&member.user.read().tag())
          .icon_url(&member.user.read().face()));
      embed = embed
        .field("Mention", member.mention(), true)
        .field("Action", "Edited message", true)
        .field("Channel", channel_mention, true)
        .field("Original message", original_content, false)
        .field("New message", new_content, false)
        .timestamp(&Utc::now())
        .footer(|f| f.text(message_id));
      embed
    })).ok();
  }

  fn message_delete(&self, _: Context, channel_id: ChannelId, message_id: MessageId) {
    let channel = match channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };
    let reader = guild_channel.read();

    let log_channel = some_or!(self.get_log_channel(reader.guild_id), return);

    let guild = match reader.guild_id.find() {
      Some(g) => g,
      None => return
    };

    let guild_reader = guild.read();

    let mut messages = self.messages.lock();
    let message = messages
      .values_mut()
      .filter_map(|x| x.get_mut(&reader.guild_id))
      .next()
      .and_then(|x| x.iter_mut().find(|m| m.id == message_id));
    let message = match message {
      Some(m) => m.clone(),
      None => return
    };

    let deletee = some_or!(guild_reader.members.get(&message.author.id).cloned().or_else(|| guild_reader.member(message.author.id).ok()), return);

    let original_content = message.content;
    let channel_mention = channel_id.mention();

    log_channel.send_message(|m| m.embed(|mut embed| {
      embed = embed
        .author(|a| a
          .name(&deletee.user.read().tag())
          .icon_url(&deletee.user.read().face()));
      embed = embed
        .field("Mention", deletee.mention(), true)
        .field("Action", "Had message deleted", true)
        .field("Channel", channel_mention, true)
        .field("Content", original_content, false)
        .timestamp(&Utc::now())
        .footer(|f| f.text(message_id));
      embed
    })).ok();
  }

  fn message(&self, _: Context, message: Message) {
    if self.count.load(Ordering::SeqCst) == 100 {
      self.count.store(0, Ordering::SeqCst);

      self.prune_messages();
    }

    let channel = match message.channel_id.get() {
      Ok(c) => c,
      Err(e) => {
        warn!("could not download channel {} for message history: {}", message.channel_id, e);
        return;
      }
    };

    let guild_channel = match channel.guild() {
      Some(g) => g,
      None => return
    };

    let reader = guild_channel.read();

    self.messages
      .lock()
      .entry(message.author.id)
      .or_default()
      .entry(reader.guild_id)
      .or_default()
      .push(message);

    self.count.fetch_add(1, Ordering::SeqCst);
  }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

#![forbid(unsafe_code)]

use crate::Executor;
use anyhow::{ensure, format_err, Result};
use executor_types::BlockExecutor;
use libra_crypto::{hash::PRE_GENESIS_BLOCK_ID, HashValue};
use libra_logger::prelude::*;
use libra_state_view::{StateView, StateViewId};
use libra_types::{
    access_path::AccessPath,
    account_config::libra_root_address,
    block_info::{BlockInfo, GENESIS_EPOCH, GENESIS_ROUND, GENESIS_TIMESTAMP_USECS},
    ledger_info::{LedgerInfo, LedgerInfoWithSignatures},
    libra_timestamp::LibraTimestampResource,
    on_chain_config::{config_address, ConfigurationResource},
    transaction::Transaction,
    waypoint::Waypoint,
};
use libra_vm::VMExecutor;
use move_core_types::move_resource::MoveResource;
use std::collections::btree_map::BTreeMap;
use storage_interface::{state_view::VerifiedStateView, DbReaderWriter, TreeState};

pub fn generate_waypoint<V: VMExecutor>(
    db: &DbReaderWriter,
    genesis_txn: &Transaction,
) -> Result<Waypoint> {
    let tree_state = db.reader.get_latest_tree_state()?;

    let committer = calculate_genesis::<V>(db, tree_state, genesis_txn)?;
    Ok(committer.waypoint)
}

/// If current version + 1 != waypoint.version(), return Ok(false) indicating skipping the txn.
/// otherwise apply the txn and commit it if the result matches the waypoint.
/// Returns Ok(true) if committed otherwise Err.
pub fn maybe_bootstrap<V: VMExecutor>(
    db: &DbReaderWriter,
    genesis_txn: &Transaction,
    waypoint: Waypoint,
) -> Result<bool> {
    let tree_state = db.reader.get_latest_tree_state()?;
    // if the waypoint is not targeted with the genesis txn, it may be either already bootstrapped, or
    // aiming for state sync to catch up.
    if tree_state.num_transactions != waypoint.version() {
        info!("Skip genesis txn");
        return Ok(false);
    }

    let committer = calculate_genesis::<V>(db, tree_state, genesis_txn)?;
    ensure!(
        waypoint == committer.waypoint(),
        "Waypoint verification failed. Expected {:?}, got {:?}.",
        waypoint,
        committer.waypoint(),
    );
    committer.commit()?;
    Ok(true)
}

pub struct GenesisCommitter<V: VMExecutor> {
    executor: Executor<V>,
    ledger_info_with_sigs: LedgerInfoWithSignatures,
    waypoint: Waypoint,
}

impl<V: VMExecutor> GenesisCommitter<V> {
    pub fn new(
        executor: Executor<V>,
        ledger_info_with_sigs: LedgerInfoWithSignatures,
    ) -> Result<Self> {
        let waypoint = Waypoint::new_epoch_boundary(ledger_info_with_sigs.ledger_info())?;

        Ok(Self {
            executor,
            ledger_info_with_sigs,
            waypoint,
        })
    }

    pub fn waypoint(&self) -> Waypoint {
        self.waypoint
    }

    pub fn commit(mut self) -> Result<()> {
        self.executor
            .commit_blocks(vec![genesis_block_id()], self.ledger_info_with_sigs)?;
        info!("Genesis commited.");
        // DB bootstrapped, avoid anything that could fail after this.

        Ok(())
    }
}

pub fn calculate_genesis<V: VMExecutor>(
    db: &DbReaderWriter,
    tree_state: TreeState,
    genesis_txn: &Transaction,
) -> Result<GenesisCommitter<V>> {
    // DB bootstrapper works on either an empty transaction accumulator or an existing block chain.
    // In the very extreme and sad situation of losing quorum among validators, we refer to the
    // second use case said above.
    let genesis_version = tree_state.num_transactions;
    let mut executor = Executor::<V>::new_on_unbootstrapped_db(db.clone(), tree_state);

    let block_id = HashValue::zero();
    let epoch = if genesis_version == 0 {
        GENESIS_EPOCH
    } else {
        let executor_trees = executor.get_executed_trees(*PRE_GENESIS_BLOCK_ID)?;
        let state_view =
            executor.get_executed_state_view(StateViewId::Miscellaneous, &executor_trees);
        get_state_epoch(&state_view)?
    };

    // Create a block with genesis_txn being the only txn. Execute it then commit it immediately.
    let result =
        executor.execute_block((block_id, vec![genesis_txn.clone()]), *PRE_GENESIS_BLOCK_ID)?;

    let root_hash = result.root_hash();
    let next_epoch_state = result
        .epoch_state()
        .as_ref()
        .ok_or_else(|| format_err!("Genesis transaction must emit a epoch change."))?;
    let executed_trees = executor.get_executed_trees(block_id)?;
    let state_view = executor.get_executed_state_view(StateViewId::Miscellaneous, &executed_trees);
    let timestamp_usecs = if genesis_version == 0 {
        // TODO(aldenhu): fix existing tests before using real timestamp and check on-chain epoch.
        GENESIS_TIMESTAMP_USECS
    } else {
        ensure!(
            epoch + 1 == get_state_epoch(&state_view)?,
            "Genesis txn didn't bump epoch."
        );
        get_state_timestamp(&state_view)?
    };

    let ledger_info_with_sigs = LedgerInfoWithSignatures::new(
        LedgerInfo::new(
            BlockInfo::new(
                epoch,
                GENESIS_ROUND,
                block_id,
                root_hash,
                genesis_version,
                timestamp_usecs,
                Some(next_epoch_state.clone()),
            ),
            HashValue::zero(), /* consensus_data_hash */
        ),
        BTreeMap::default(), /* signatures */
    );

    let committer = GenesisCommitter::new(executor, ledger_info_with_sigs)?;
    info!(
        "Genesis calculated: ledger_info_with_sigs {:?}, waypoint {:?}",
        committer.ledger_info_with_sigs, committer.waypoint,
    );
    Ok(committer)
}

fn get_state_timestamp(state_view: &VerifiedStateView) -> Result<u64> {
    let rsrc_bytes = &state_view
        .get(&AccessPath::new(
            libra_root_address(),
            LibraTimestampResource::resource_path(),
        ))?
        .ok_or_else(|| format_err!("LibraTimestampResource missing."))?;
    let rsrc = lcs::from_bytes::<LibraTimestampResource>(&rsrc_bytes)?;
    Ok(rsrc.libra_timestamp.microseconds)
}

fn get_state_epoch(state_view: &VerifiedStateView) -> Result<u64> {
    let rsrc_bytes = &state_view
        .get(&AccessPath::new(
            config_address(),
            ConfigurationResource::resource_path(),
        ))?
        .ok_or_else(|| format_err!("ConfigurationResource missing."))?;
    let rsrc = lcs::from_bytes::<ConfigurationResource>(&rsrc_bytes)?;
    Ok(rsrc.epoch())
}

fn genesis_block_id() -> HashValue {
    HashValue::zero()
}
<commit_msg>[db-bootstrap] better error message<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

#![forbid(unsafe_code)]

use crate::Executor;
use anyhow::{ensure, format_err, Result};
use executor_types::BlockExecutor;
use libra_crypto::{hash::PRE_GENESIS_BLOCK_ID, HashValue};
use libra_logger::prelude::*;
use libra_state_view::{StateView, StateViewId};
use libra_types::{
    access_path::AccessPath,
    account_config::libra_root_address,
    block_info::{BlockInfo, GENESIS_EPOCH, GENESIS_ROUND, GENESIS_TIMESTAMP_USECS},
    ledger_info::{LedgerInfo, LedgerInfoWithSignatures},
    libra_timestamp::LibraTimestampResource,
    on_chain_config::{config_address, ConfigurationResource},
    transaction::Transaction,
    waypoint::Waypoint,
};
use libra_vm::VMExecutor;
use move_core_types::move_resource::MoveResource;
use std::collections::btree_map::BTreeMap;
use storage_interface::{state_view::VerifiedStateView, DbReaderWriter, TreeState};

pub fn generate_waypoint<V: VMExecutor>(
    db: &DbReaderWriter,
    genesis_txn: &Transaction,
) -> Result<Waypoint> {
    let tree_state = db.reader.get_latest_tree_state()?;

    let committer = calculate_genesis::<V>(db, tree_state, genesis_txn)?;
    Ok(committer.waypoint)
}

/// If current version + 1 != waypoint.version(), return Ok(false) indicating skipping the txn.
/// otherwise apply the txn and commit it if the result matches the waypoint.
/// Returns Ok(true) if committed otherwise Err.
pub fn maybe_bootstrap<V: VMExecutor>(
    db: &DbReaderWriter,
    genesis_txn: &Transaction,
    waypoint: Waypoint,
) -> Result<bool> {
    let tree_state = db.reader.get_latest_tree_state()?;
    // if the waypoint is not targeted with the genesis txn, it may be either already bootstrapped, or
    // aiming for state sync to catch up.
    if tree_state.num_transactions != waypoint.version() {
        info!(waypoint = %waypoint, "Skip genesis txn.");
        return Ok(false);
    }

    let committer = calculate_genesis::<V>(db, tree_state, genesis_txn)?;
    ensure!(
        waypoint == committer.waypoint(),
        "Waypoint verification failed. Expected {:?}, got {:?}.",
        waypoint,
        committer.waypoint(),
    );
    committer.commit()?;
    Ok(true)
}

pub struct GenesisCommitter<V: VMExecutor> {
    executor: Executor<V>,
    ledger_info_with_sigs: LedgerInfoWithSignatures,
    waypoint: Waypoint,
}

impl<V: VMExecutor> GenesisCommitter<V> {
    pub fn new(
        executor: Executor<V>,
        ledger_info_with_sigs: LedgerInfoWithSignatures,
    ) -> Result<Self> {
        let waypoint = Waypoint::new_epoch_boundary(ledger_info_with_sigs.ledger_info())?;

        Ok(Self {
            executor,
            ledger_info_with_sigs,
            waypoint,
        })
    }

    pub fn waypoint(&self) -> Waypoint {
        self.waypoint
    }

    pub fn commit(mut self) -> Result<()> {
        self.executor
            .commit_blocks(vec![genesis_block_id()], self.ledger_info_with_sigs)?;
        info!("Genesis commited.");
        // DB bootstrapped, avoid anything that could fail after this.

        Ok(())
    }
}

pub fn calculate_genesis<V: VMExecutor>(
    db: &DbReaderWriter,
    tree_state: TreeState,
    genesis_txn: &Transaction,
) -> Result<GenesisCommitter<V>> {
    // DB bootstrapper works on either an empty transaction accumulator or an existing block chain.
    // In the very extreme and sad situation of losing quorum among validators, we refer to the
    // second use case said above.
    let genesis_version = tree_state.num_transactions;
    let mut executor = Executor::<V>::new_on_unbootstrapped_db(db.clone(), tree_state);

    let block_id = HashValue::zero();
    let epoch = if genesis_version == 0 {
        GENESIS_EPOCH
    } else {
        let executor_trees = executor.get_executed_trees(*PRE_GENESIS_BLOCK_ID)?;
        let state_view =
            executor.get_executed_state_view(StateViewId::Miscellaneous, &executor_trees);
        get_state_epoch(&state_view)?
    };

    // Create a block with genesis_txn being the only txn. Execute it then commit it immediately.
    let result =
        executor.execute_block((block_id, vec![genesis_txn.clone()]), *PRE_GENESIS_BLOCK_ID)?;

    let root_hash = result.root_hash();
    let next_epoch_state = result
        .epoch_state()
        .as_ref()
        .ok_or_else(|| format_err!("Genesis transaction must emit a epoch change."))?;
    let executed_trees = executor.get_executed_trees(block_id)?;
    let state_view = executor.get_executed_state_view(StateViewId::Miscellaneous, &executed_trees);
    let timestamp_usecs = if genesis_version == 0 {
        // TODO(aldenhu): fix existing tests before using real timestamp and check on-chain epoch.
        GENESIS_TIMESTAMP_USECS
    } else {
        ensure!(
            epoch + 1 == get_state_epoch(&state_view)?,
            "Genesis txn didn't bump epoch."
        );
        get_state_timestamp(&state_view)?
    };

    let ledger_info_with_sigs = LedgerInfoWithSignatures::new(
        LedgerInfo::new(
            BlockInfo::new(
                epoch,
                GENESIS_ROUND,
                block_id,
                root_hash,
                genesis_version,
                timestamp_usecs,
                Some(next_epoch_state.clone()),
            ),
            HashValue::zero(), /* consensus_data_hash */
        ),
        BTreeMap::default(), /* signatures */
    );

    let committer = GenesisCommitter::new(executor, ledger_info_with_sigs)?;
    info!(
        "Genesis calculated: ledger_info_with_sigs {:?}, waypoint {:?}",
        committer.ledger_info_with_sigs, committer.waypoint,
    );
    Ok(committer)
}

fn get_state_timestamp(state_view: &VerifiedStateView) -> Result<u64> {
    let rsrc_bytes = &state_view
        .get(&AccessPath::new(
            libra_root_address(),
            LibraTimestampResource::resource_path(),
        ))?
        .ok_or_else(|| format_err!("LibraTimestampResource missing."))?;
    let rsrc = lcs::from_bytes::<LibraTimestampResource>(&rsrc_bytes)?;
    Ok(rsrc.libra_timestamp.microseconds)
}

fn get_state_epoch(state_view: &VerifiedStateView) -> Result<u64> {
    let rsrc_bytes = &state_view
        .get(&AccessPath::new(
            config_address(),
            ConfigurationResource::resource_path(),
        ))?
        .ok_or_else(|| format_err!("ConfigurationResource missing."))?;
    let rsrc = lcs::from_bytes::<ConfigurationResource>(&rsrc_bytes)?;
    Ok(rsrc.epoch())
}

fn genesis_block_id() -> HashValue {
    HashValue::zero()
}
<|endoftext|>


<commit_before>use std::slice::{Iter, IterMut};

static BLOCK_SEPARATOR: &str = ",";

/// Used to build a block (column | row), specifying additional details.
#[derive(Default)]
pub struct BlockBuilder {
    size: BlockSize,
    min_size: f64,
    max_size: f64,
}

impl BlockBuilder {
    /// Creates a new `BlockBuilder` with default values.
    pub fn new() -> Self {
        BlockBuilder::default()
    }

    /// Inserts a new size.
    pub fn size(mut self, size: BlockSize) -> Self {
        self.size = size;
        self
    }

    /// Inserts a new min size.
    pub fn min_size(mut self, min_size: f64) -> Self {
        self.min_size = min_size;
        self
    }

    /// Inserts a new max size.
    pub fn max_size(mut self, max_size: f64) -> Self {
        self.max_size = max_size;
        self
    }

    /// Builds a block property.
    pub fn build(self) -> Block {
        Block {
            size: self.size,
            min_size: self.min_size,
            max_size: self.max_size,
            current_size: 0.0,
        }
    }
}

/// Used to define a block inside a `Grid`.
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Block {
    pub size: BlockSize,
    pub min_size: f64,
    pub max_size: f64,
    current_size: f64,
}

impl Block {
    /// Creates a new `BlockBuilder` object with default values.
    #[inline]
    pub fn create() -> BlockBuilder {
        BlockBuilder::new()
    }

    /// Gets the block size.
    pub fn size(&self) -> BlockSize {
        self.size
    }

    /// Gets the current size.
    pub fn current_size(&self) -> f64 {
        self.current_size
    }

    /// Sets the current size.
    pub fn set_current_size(&mut self, size: f64) {
        self.current_size = if self.min_size == 0.0 && self.max_size == 0.0 && size > 0.0 {
            size
        } else if size < self.min_size && self.min_size > 0.0 {
            self.min_size
        } else if size > self.max_size && self.max_size > 0.0 {
            self.max_size
        } else {
            size
        };
    }
}

impl From<&str> for Block {
    fn from(t: &str) -> Self {
        if let Ok(size) = t.parse::<f64>() {
            return Block::create().size(BlockSize::Size(size)).build();
        }
        match t {
            "Auto" | "auto" => Block::create().size(BlockSize::Auto).build(),
            _ => Block::create().size(BlockSize::Stretch).build(),
        }
    }
}

impl From<f64> for Block {
    fn from(t: f64) -> Self {
        Block::create().size(BlockSize::Size(t)).build()
    }
}

impl From<i32> for Block {
    fn from(t: i32) -> Self {
        Block::create().size(BlockSize::Size(t.into())).build()
    }
}

/// Used to define the size of a grid block.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BlockSize {
    /// Block is measured by the largest child.
    Auto,

    /// Block expands to the rest available size.
    Stretch,

    /// Defines a fixed size for the block.
    Size(f64),
}

impl Default for BlockSize {
    fn default() -> Self {
        BlockSize::Stretch
    }
}

/// Used to build `blocks`, that will group `block` structs.
#[derive(Default)]
pub struct BlocksBuilder {
    blocks: Vec<Block>,
}

/// Used to build a blocks, specifying additional details.
impl BlocksBuilder {
    /// Creates a new `BlocksBuilder` with default values.
    pub fn new() -> Self {
        BlocksBuilder::default()
    }

    /// Inserts a new block.
    pub fn push<C: Into<Block>>(mut self, block: C) -> Self {
        self.blocks.push(block.into());
        self
    }

    /// Inserts a new block.
    #[inline(always)]
    #[deprecated = "Use push instead"]
    pub fn block<C: Into<Block>>(self, block: C) -> Self {
        self.push(block)
    }

    /// Inserts a list of blocks.
    pub fn blocks<R: Into<Block> + Clone>(mut self, blocks: &[R]) -> Self {
        for block in blocks.to_vec() {
            self.blocks.push(block.into());
        }
        self
    }

    /// Inserts the given block as often as given.
    pub fn repeat<R: Into<Block> + Copy>(mut self, block: R, count: usize) -> Self {
        for _ in 0..count {
            self.blocks.push(block.into())
        }
        self
    }

    /// Builds the blocks.
    pub fn build(self) -> Blocks {
        Blocks(self.blocks)
    }
}

impl From<BlocksBuilder> for Blocks {
    fn from(builder: BlocksBuilder) -> Self {
        builder.build()
    }
}

/// Helper struct used to group block properties.
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Blocks(pub Vec<Block>);

/// Alias type for `Blocks`. Provided to keep old api calls working.
#[deprecated = "Will be removed on 0.3.1-alpha5. Use `Blocks` instead"]
pub type Columns = Blocks;

/// Alias type for `Blocks`. Provided to keep old api calls working.
#[deprecated = "Will be removed on 0.3.1-alpha5. Use `Blocks` instead"]
pub type Rows = Blocks;

impl Blocks {
    /// Creates a new `BlocksBuilder` object with default values.
    #[inline]
    pub fn create() -> BlocksBuilder {
        BlocksBuilder::new()
    }

    /// Returns the number of elements in the blocks list, also referred to as its 'length'.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Returns a boolean if the block is empty.
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// Returns a reference to a block.
    pub fn get(&self, block: usize) -> Option<&Block> {
        self.0.get(block)
    }

    /// Returns a mutable reference to a block.
    pub fn get_mut(&mut self, block: usize) -> Option<&mut Block> {
        self.0.get_mut(block)
    }

    /// Returns an iterator over the slice.
    pub fn iter(&self) -> Iter<Block> {
        self.0.iter()
    }

    /// Returns a mutable iterator over the slice.
    pub fn iter_mut(&mut self) -> IterMut<Block> {
        self.0.iter_mut()
    }
}

impl From<&str> for Blocks {
    fn from(blocks: &str) -> Self {
        let blocks = blocks.replace(" ", "");
        let mut block_builder = BlocksBuilder::new();
        for block in blocks.split(BLOCK_SEPARATOR) {
            block_builder = block_builder.push(Block::from(block));
        }

        block_builder.build()
    }
}

impl From<String> for Blocks {
    fn from(blocks: String) -> Self {
        Self::from(blocks.as_str())
    }
}

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

    const ERROR: f64 = f64::EPSILON;

    #[test]
    fn test_size() {
        let size = BlockSize::Size(64.0);

        let builder = BlockBuilder::new();
        let block = builder.size(size).build();

        assert_eq!(block.size, size);
    }

    #[test]
    fn test_min_size() {
        let min_size = 64.0;

        let builder = BlockBuilder::new();
        let block = builder.min_size(min_size).build();

        assert!((block.min_size - min_size).abs() < ERROR);
    }

    #[test]
    fn test_max_size() {
        let max_size = 64.0;

        let builder = BlockBuilder::new();
        let block = builder.max_size(max_size).build();

        assert!((block.max_size - max_size) < ERROR);
    }

    #[test]
    fn test_set_current_size() {
        let out_one_size = 10.0;
        let out_two_size = 66.0;
        let min_size = 14.0;
        let max_size = 64.0;

        let builder = BlockBuilder::new();
        let mut block = builder.min_size(min_size).max_size(max_size).build();

        block.set_current_size(out_one_size);
        assert!((block.current_size() - min_size).abs() < ERROR);

        block.set_current_size(out_two_size);
        assert!((block.current_size() - max_size).abs() < ERROR);
    }

    #[test]
    fn test_block() {
        let builder = BlocksBuilder::new();
        let blocks = builder.build();

        assert_eq!(blocks.len(), 0);

        let builder = BlocksBuilder::new();
        let blocks = builder
            .push(Block::create().build())
            .push(Block::create().build())
            .build();

        assert_eq!(blocks.len(), 2);
    }

    #[test]
    fn test_block_size_into() {
        let block: Block = "Auto".into();
        assert_eq!(block.size(), BlockSize::Auto);

        let block: Block = "auto".into();
        assert_eq!(block.size(), BlockSize::Auto);

        let block: Block = "Stretch".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "stretch".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "*".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "other".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = 64.0.into();
        assert_eq!(block.size(), BlockSize::Size(64.0));
    }
}
<commit_msg>orbtk_widgets: update `block`<commit_after>use std::slice::{Iter, IterMut};

static BLOCK_SEPARATOR: &str = ",";

/// Used to build a block (column | row), specifying additional details.
#[derive(Default)]
pub struct BlockBuilder {
    size: BlockSize,
    min_size: f64,
    max_size: f64,
}

impl BlockBuilder {
    /// Creates a new `BlockBuilder` with default values.
    pub fn new() -> Self {
        BlockBuilder::default()
    }

    /// Inserts a new size.
    pub fn size(mut self, size: BlockSize) -> Self {
        self.size = size;
        self
    }

    /// Inserts a new min size.
    pub fn min_size(mut self, min_size: f64) -> Self {
        self.min_size = min_size;
        self
    }

    /// Inserts a new max size.
    pub fn max_size(mut self, max_size: f64) -> Self {
        self.max_size = max_size;
        self
    }

    /// Builds a block property.
    pub fn build(self) -> Block {
        Block {
            size: self.size,
            min_size: self.min_size,
            max_size: self.max_size,
            current_size: 0.0,
        }
    }
}

/// Used to define a block inside a `Grid`.
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Block {
    pub size: BlockSize,
    pub min_size: f64,
    pub max_size: f64,
    current_size: f64,
}

impl Block {
    /// Creates a new `BlockBuilder` object with default values.
    #[inline]
    pub fn create() -> BlockBuilder {
        BlockBuilder::new()
    }

    /// Gets the block size.
    pub fn size(&self) -> BlockSize {
        self.size
    }

    /// Gets the current size.
    pub fn current_size(&self) -> f64 {
        self.current_size
    }

    /// Sets the current size.
    pub fn set_current_size(&mut self, size: f64) {
        self.current_size = if self.min_size == 0.0 && self.max_size == 0.0 && size > 0.0 {
            size
        } else if size < self.min_size && self.min_size > 0.0 {
            self.min_size
        } else if size > self.max_size && self.max_size > 0.0 {
            self.max_size
        } else {
            size
        };
    }
}

impl From<&str> for Block {
    fn from(t: &str) -> Self {
        if let Ok(size) = t.parse::<f64>() {
            return Block::create().size(BlockSize::Size(size)).build();
        }
        match t {
            "Auto" | "auto" => Block::create().size(BlockSize::Auto).build(),
            _ => Block::create().size(BlockSize::Stretch).build(),
        }
    }
}

impl From<f64> for Block {
    fn from(t: f64) -> Self {
        Block::create().size(BlockSize::Size(t)).build()
    }
}

impl From<i32> for Block {
    fn from(t: i32) -> Self {
        Block::create().size(BlockSize::Size(t.into())).build()
    }
}

/// Used to define the size of a grid block.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BlockSize {
    /// Block is measured by the largest child.
    Auto,

    /// Block expands to the rest available size.
    Stretch,

    /// Defines a fixed size for the block.
    Size(f64),
}

impl Default for BlockSize {
    fn default() -> Self {
        BlockSize::Stretch
    }
}

/// Used to build `blocks`, that will group `block` structs.
#[derive(Default)]
pub struct BlocksBuilder {
    blocks: Vec<Block>,
}

/// Used to build a blocks, specifying additional details.
impl BlocksBuilder {
    /// Creates a new `BlocksBuilder` with default values.
    pub fn new() -> Self {
        BlocksBuilder::default()
    }

    /// Inserts a new block.
    pub fn push<C: Into<Block>>(mut self, block: C) -> Self {
        self.blocks.push(block.into());
        self
    }

    /// Inserts a new block.
    #[inline(always)]
    #[deprecated = "Use push instead"]
    pub fn block<C: Into<Block>>(self, block: C) -> Self {
        self.push(block)
    }

    /// Inserts a list of blocks.
    pub fn blocks<R: Into<Block> + Clone>(mut self, blocks: &[R]) -> Self {
        for block in blocks.to_vec() {
            self.blocks.push(block.into());
        }
        self
    }

    /// Inserts the given block as often as given.
    pub fn repeat<R: Into<Block> + Copy>(mut self, block: R, count: usize) -> Self {
        for _ in 0..count {
            self.blocks.push(block.into())
        }
        self
    }

    /// Builds the blocks.
    pub fn build(self) -> Blocks {
        Blocks(self.blocks)
    }
}

impl From<BlocksBuilder> for Blocks {
    fn from(builder: BlocksBuilder) -> Self {
        builder.build()
    }
}

/// Helper struct used to group block properties.
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Blocks(pub Vec<Block>);

/// Alias type for `Blocks`. Provided to keep old api calls working.
#[deprecated = "Will be removed on 0.3.1-alpha5. Use `Blocks` instead"]
pub type Columns = Blocks;

/// Alias type for `Blocks`. Provided to keep old api calls working.
#[deprecated = "Will be removed on 0.3.1-alpha5. Use `Blocks` instead"]
pub type Rows = Blocks;

impl Blocks {
    /// Creates a new `BlocksBuilder` object with default values.
    #[inline]
    pub fn create() -> BlocksBuilder {
        BlocksBuilder::new()
    }

    /// Returns a reference to a block.
    pub fn get(&self, block: usize) -> Option<&Block> {
        self.0.get(block)
    }

    /// Returns a mutable reference to a block.
    pub fn get_mut(&mut self, block: usize) -> Option<&mut Block> {
        self.0.get_mut(block)
    }

    /// Returns a boolean if the block is empty.
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// Returns an iterator over the slice.
    pub fn iter(&self) -> Iter<Block> {
        self.0.iter()
    }

    /// Returns a mutable iterator over the slice.
    pub fn iter_mut(&mut self) -> IterMut<Block> {
        self.0.iter_mut()
    }

    /// Returns the number of elements in the blocks list, also referred to as its 'length'.
    pub fn len(&self) -> usize {
        self.0.len()
    }
}

impl From<&str> for Blocks {
    fn from(blocks: &str) -> Self {
        let blocks = blocks.replace(" ", "");
        let mut block_builder = BlocksBuilder::new();
        for block in blocks.split(BLOCK_SEPARATOR) {
            block_builder = block_builder.push(Block::from(block));
        }

        block_builder.build()
    }
}

impl From<String> for Blocks {
    fn from(blocks: String) -> Self {
        Self::from(blocks.as_str())
    }
}

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

    const ERROR: f64 = f64::EPSILON;

    #[test]
    fn test_size() {
        let size = BlockSize::Size(64.0);

        let builder = BlockBuilder::new();
        let block = builder.size(size).build();

        assert_eq!(block.size, size);
    }

    #[test]
    fn test_min_size() {
        let min_size = 64.0;

        let builder = BlockBuilder::new();
        let block = builder.min_size(min_size).build();

        assert!((block.min_size - min_size).abs() < ERROR);
    }

    #[test]
    fn test_max_size() {
        let max_size = 64.0;

        let builder = BlockBuilder::new();
        let block = builder.max_size(max_size).build();

        assert!((block.max_size - max_size) < ERROR);
    }

    #[test]
    fn test_set_current_size() {
        let out_one_size = 10.0;
        let out_two_size = 66.0;
        let min_size = 14.0;
        let max_size = 64.0;

        let builder = BlockBuilder::new();
        let mut block = builder.min_size(min_size).max_size(max_size).build();

        block.set_current_size(out_one_size);
        assert!((block.current_size() - min_size).abs() < ERROR);

        block.set_current_size(out_two_size);
        assert!((block.current_size() - max_size).abs() < ERROR);
    }

    #[test]
    fn test_block() {
        let builder = BlocksBuilder::new();
        let blocks = builder.build();

        assert_eq!(blocks.len(), 0);

        let builder = BlocksBuilder::new();
        let blocks = builder
            .push(Block::create().build())
            .push(Block::create().build())
            .build();

        assert_eq!(blocks.len(), 2);
    }

    #[test]
    fn test_block_size_into() {
        let block: Block = "Auto".into();
        assert_eq!(block.size(), BlockSize::Auto);

        let block: Block = "auto".into();
        assert_eq!(block.size(), BlockSize::Auto);

        let block: Block = "Stretch".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "stretch".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "*".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = "other".into();
        assert_eq!(block.size(), BlockSize::Stretch);

        let block: Block = 64.0.into();
        assert_eq!(block.size(), BlockSize::Size(64.0));
    }
}
<|endoftext|>