<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::Bindings::HTMLCollectionBinding;
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{namespace_from_domstring, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers, ElementHelpers};
use dom::node::{Node, NodeHelpers, TreeIterator};
use dom::window::Window;
use util::str::{DOMString, split_html_space_chars};

use std::ascii::AsciiExt;
use std::iter::{FilterMap, Skip};
use string_cache::{Atom, Namespace};

pub trait CollectionFilter : JSTraceable {
    fn filter<'a>(&self, elem: &'a Element, root: &'a Node) -> bool;
}

#[derive(JSTraceable)]
#[must_root]
pub struct Collection(JS<Node>, Box<CollectionFilter + 'static>);

#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLCollection {
    reflector_: Reflector,
    #[ignore_heap_size_of = "Contains a trait object; can't measure due to #6870"]
    collection: Collection,
}

impl HTMLCollection {
    fn new_inherited(collection: Collection) -> HTMLCollection {
        HTMLCollection {
            reflector_: Reflector::new(),
            collection: collection,
        }
    }

    pub fn new(window: &Window, collection: Collection) -> Root<HTMLCollection> {
        reflect_dom_object(box HTMLCollection::new_inherited(collection),
                           GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
    }
}

impl HTMLCollection {
    pub fn create(window: &Window, root: &Node,
                  filter: Box<CollectionFilter + 'static>) -> Root<HTMLCollection> {
        HTMLCollection::new(window, Collection(JS::from_ref(root), filter))
    }

    fn all_elements(window: &Window, root: &Node,
                    namespace_filter: Option<Namespace>) -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct AllElementFilter {
            namespace_filter: Option<Namespace>
        }
        impl CollectionFilter for AllElementFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                match self.namespace_filter {
                    None => true,
                    Some(ref namespace) => *elem.namespace() == *namespace
                }
            }
        }
        let filter = AllElementFilter {namespace_filter: namespace_filter};
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_tag_name(window: &Window, root: &Node, tag: DOMString)
                       -> Root<HTMLCollection> {
        if tag == "*" {
            return HTMLCollection::all_elements(window, root, None);
        }

        #[derive(JSTraceable, HeapSizeOf)]
        struct TagNameFilter {
            tag: Atom,
            ascii_lower_tag: Atom,
        }
        impl CollectionFilter for TagNameFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                if elem.html_element_in_html_document() {
                    *elem.local_name() == self.ascii_lower_tag
                } else {
                    *elem.local_name() == self.tag
                }
            }
        }
        let filter = TagNameFilter {
            tag: Atom::from_slice(&tag),
            ascii_lower_tag: Atom::from_slice(&tag.to_ascii_lowercase()),
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_tag_name_ns(window: &Window, root: &Node, tag: DOMString,
                          maybe_ns: Option<DOMString>) -> Root<HTMLCollection> {
        let namespace_filter = match maybe_ns {
            Some(ref namespace) if namespace == &"*" => None,
            ns => Some(namespace_from_domstring(ns)),
        };

        if tag == "*" {
            return HTMLCollection::all_elements(window, root, namespace_filter);
        }
        #[derive(JSTraceable, HeapSizeOf)]
        struct TagNameNSFilter {
            tag: Atom,
            namespace_filter: Option<Namespace>
        }
        impl CollectionFilter for TagNameNSFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                let ns_match = match self.namespace_filter {
                    Some(ref namespace) => {
                        *elem.namespace() == *namespace
                    },
                    None => true
                };
                ns_match && *elem.local_name() == self.tag
            }
        }
        let filter = TagNameNSFilter {
            tag: Atom::from_slice(&tag),
            namespace_filter: namespace_filter
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_class_name(window: &Window, root: &Node, classes: DOMString)
                         -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct ClassNameFilter {
            classes: Vec<Atom>
        }
        impl CollectionFilter for ClassNameFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                self.classes.iter().all(|class| elem.has_class(class))
            }
        }
        let filter = ClassNameFilter {
            classes: split_html_space_chars(&classes).map(|class| {
                         Atom::from_slice(class)
                     }).collect()
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn children(window: &Window, root: &Node) -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct ElementChildFilter;
        impl CollectionFilter for ElementChildFilter {
            fn filter(&self, elem: &Element, root: &Node) -> bool {
                root.is_parent_of(NodeCast::from_ref(elem))
            }
        }
        HTMLCollection::create(window, root, box ElementChildFilter)
    }

    fn traverse(root: &Node)
                -> FilterMap<Skip<TreeIterator>,
                             fn(Root<Node>) -> Option<Root<Element>>> {
        fn to_temporary(node: Root<Node>) -> Option<Root<Element>> {
            ElementCast::to_root(node)
        }
        root.traverse_preorder()
            .skip(1)
            .filter_map(to_temporary)
    }
}

impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
    // https://dom.spec.whatwg.org/#dom-htmlcollection-length
    fn Length(self) -> u32 {
        let ref root = self.collection.0.root();
        let ref filter = self.collection.1;
        HTMLCollection::traverse(root.r())
            .filter(|element| filter.filter(element.r(), root.r()))
            .count() as u32
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-item
    fn Item(self, index: u32) -> Option<Root<Element>> {
        let index = index as usize;
        let ref root = self.collection.0.root();
        let ref filter = self.collection.1;
        HTMLCollection::traverse(root.r())
            .filter(|element| filter.filter(element.r(), root.r()))
            .nth(index)
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
    fn NamedItem(self, key: DOMString) -> Option<Root<Element>> {
        // Step 1.
        if key.is_empty() {
            return None;
        }

        // Step 2.
        let ref root = self.collection.0.root();
        let ref filter = self.collection.1;
        HTMLCollection::traverse(root.r())
            .filter(|element| filter.filter(element.r(), root.r()))
            .find(|elem| {
                elem.r().get_string_attribute(&atom!("name")) == key ||
                elem.r().get_string_attribute(&atom!("id")) == key})
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-item
    fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Element>> {
        let maybe_elem = self.Item(index);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    // check-tidy: no specs after this line
    fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Element>> {
        let maybe_elem = self.NamedItem(name);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    // https://dom.spec.whatwg.org/#interface-htmlcollection
    fn SupportedPropertyNames(self) -> Vec<DOMString> {
        // Step 1
        let mut result = vec![];

        // Step 2
        let root = self.collection.0.root();
        let ref filter = self.collection.1;
        let elems = HTMLCollection::traverse(root.r()).filter(|element| filter.filter(element.r(), root.r()));
        for elem in elems {
            // Step 2.1
            let id_attr = elem.get_string_attribute(&atom!("id"));
            if !id_attr.is_empty() && !result.contains(&id_attr) {
                result.push(id_attr)
            }
            // Step 2.2
            let name_attr = elem.get_string_attribute(&atom!("name"));
            if !name_attr.is_empty() && !result.contains(&name_attr) && *elem.namespace() == ns!(HTML) {
                result.push(name_attr)
            }
        }

        // Step 3
        result
    }
}
<commit_msg>Auto merge of #7299 - frewsxcv:cleanup-htmlcollection-iteration, r=Ms2ger<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::Bindings::HTMLCollectionBinding;
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{namespace_from_domstring, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers, ElementHelpers};
use dom::node::{Node, NodeHelpers, TreeIterator};
use dom::window::Window;
use util::str::{DOMString, split_html_space_chars};

use std::ascii::AsciiExt;
use string_cache::{Atom, Namespace};

pub trait CollectionFilter : JSTraceable {
    fn filter<'a>(&self, elem: &'a Element, root: &'a Node) -> bool;
}

#[derive(JSTraceable)]
#[must_root]
pub struct Collection(JS<Node>, Box<CollectionFilter + 'static>);

#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLCollection {
    reflector_: Reflector,
    #[ignore_heap_size_of = "Contains a trait object; can't measure due to #6870"]
    collection: Collection,
}

impl HTMLCollection {
    fn new_inherited(collection: Collection) -> HTMLCollection {
        HTMLCollection {
            reflector_: Reflector::new(),
            collection: collection,
        }
    }

    pub fn new(window: &Window, collection: Collection) -> Root<HTMLCollection> {
        reflect_dom_object(box HTMLCollection::new_inherited(collection),
                           GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
    }
}

impl HTMLCollection {
    pub fn create(window: &Window, root: &Node,
                  filter: Box<CollectionFilter + 'static>) -> Root<HTMLCollection> {
        HTMLCollection::new(window, Collection(JS::from_ref(root), filter))
    }

    fn all_elements(window: &Window, root: &Node,
                    namespace_filter: Option<Namespace>) -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct AllElementFilter {
            namespace_filter: Option<Namespace>
        }
        impl CollectionFilter for AllElementFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                match self.namespace_filter {
                    None => true,
                    Some(ref namespace) => *elem.namespace() == *namespace
                }
            }
        }
        let filter = AllElementFilter {namespace_filter: namespace_filter};
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_tag_name(window: &Window, root: &Node, tag: DOMString)
                       -> Root<HTMLCollection> {
        if tag == "*" {
            return HTMLCollection::all_elements(window, root, None);
        }

        #[derive(JSTraceable, HeapSizeOf)]
        struct TagNameFilter {
            tag: Atom,
            ascii_lower_tag: Atom,
        }
        impl CollectionFilter for TagNameFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                if elem.html_element_in_html_document() {
                    *elem.local_name() == self.ascii_lower_tag
                } else {
                    *elem.local_name() == self.tag
                }
            }
        }
        let filter = TagNameFilter {
            tag: Atom::from_slice(&tag),
            ascii_lower_tag: Atom::from_slice(&tag.to_ascii_lowercase()),
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_tag_name_ns(window: &Window, root: &Node, tag: DOMString,
                          maybe_ns: Option<DOMString>) -> Root<HTMLCollection> {
        let namespace_filter = match maybe_ns {
            Some(ref namespace) if namespace == &"*" => None,
            ns => Some(namespace_from_domstring(ns)),
        };

        if tag == "*" {
            return HTMLCollection::all_elements(window, root, namespace_filter);
        }
        #[derive(JSTraceable, HeapSizeOf)]
        struct TagNameNSFilter {
            tag: Atom,
            namespace_filter: Option<Namespace>
        }
        impl CollectionFilter for TagNameNSFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                let ns_match = match self.namespace_filter {
                    Some(ref namespace) => {
                        *elem.namespace() == *namespace
                    },
                    None => true
                };
                ns_match && *elem.local_name() == self.tag
            }
        }
        let filter = TagNameNSFilter {
            tag: Atom::from_slice(&tag),
            namespace_filter: namespace_filter
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn by_class_name(window: &Window, root: &Node, classes: DOMString)
                         -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct ClassNameFilter {
            classes: Vec<Atom>
        }
        impl CollectionFilter for ClassNameFilter {
            fn filter(&self, elem: &Element, _root: &Node) -> bool {
                self.classes.iter().all(|class| elem.has_class(class))
            }
        }
        let filter = ClassNameFilter {
            classes: split_html_space_chars(&classes).map(|class| {
                         Atom::from_slice(class)
                     }).collect()
        };
        HTMLCollection::create(window, root, box filter)
    }

    pub fn children(window: &Window, root: &Node) -> Root<HTMLCollection> {
        #[derive(JSTraceable, HeapSizeOf)]
        struct ElementChildFilter;
        impl CollectionFilter for ElementChildFilter {
            fn filter(&self, elem: &Element, root: &Node) -> bool {
                root.is_parent_of(NodeCast::from_ref(elem))
            }
        }
        HTMLCollection::create(window, root, box ElementChildFilter)
    }

    fn elements_iter(&self) -> HTMLCollectionElementsIter {
        let ref filter = self.collection.1;
        let root = self.collection.0.root();
        let mut node_iter = root.traverse_preorder();
        let _ = node_iter.next();  // skip the root node
        HTMLCollectionElementsIter {
            node_iter: node_iter,
            root: root,
            filter: filter,
        }
    }
}

struct HTMLCollectionElementsIter<'a> {
    node_iter: TreeIterator,
    root: Root<Node>,
    filter: &'a Box<CollectionFilter>,
}

impl<'a> Iterator for HTMLCollectionElementsIter<'a> {
    type Item = Root<Element>;

    fn next(&mut self) -> Option<Self::Item> {
        let filter = self.filter;
        let root = self.root.r();
        self.node_iter.by_ref()
                      .filter_map(ElementCast::to_root)
                      .filter(|element| filter.filter(element.r(), root))
                      .next()
    }
}

impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
    // https://dom.spec.whatwg.org/#dom-htmlcollection-length
    fn Length(self) -> u32 {
        self.elements_iter().count() as u32
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-item
    fn Item(self, index: u32) -> Option<Root<Element>> {
        self.elements_iter().nth(index as usize)
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
    fn NamedItem(self, key: DOMString) -> Option<Root<Element>> {
        // Step 1.
        if key.is_empty() {
            return None;
        }

        // Step 2.
        self.elements_iter().find(|elem| {
            elem.r().get_string_attribute(&atom!("name")) == key ||
            elem.r().get_string_attribute(&atom!("id")) == key
        })
    }

    // https://dom.spec.whatwg.org/#dom-htmlcollection-item
    fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Element>> {
        let maybe_elem = self.Item(index);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    // check-tidy: no specs after this line
    fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Element>> {
        let maybe_elem = self.NamedItem(name);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    // https://dom.spec.whatwg.org/#interface-htmlcollection
    fn SupportedPropertyNames(self) -> Vec<DOMString> {
        // Step 1
        let mut result = vec![];

        // Step 2
        for elem in self.elements_iter() {
            // Step 2.1
            let id_attr = elem.get_string_attribute(&atom!("id"));
            if !id_attr.is_empty() && !result.contains(&id_attr) {
                result.push(id_attr)
            }
            // Step 2.2
            let name_attr = elem.get_string_attribute(&atom!("name"));
            if !name_attr.is_empty() && !result.contains(&name_attr) && *elem.namespace() == ns!(HTML) {
                result.push(name_attr)
            }
        }

        // Step 3
        result
    }
}
<|endoftext|>


<commit_before>use std::str::CharIndices;
use std::iter::Peekable;
use std::result;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;

mod error;
pub use self::error::Error;
pub type Result<T> = result::Result<T, Error>;

#[derive(PartialEq, Debug)]
pub enum Token<'a> {
  Eof,
  Punctuator(Punctuator, usize, usize),
  Name(&'a str, usize, usize),
  IntValue(&'a str, usize, usize),
  FloatValue(&'a str, usize, usize),
  StringValue(String, usize, usize),
}

#[derive(PartialEq, Debug)]
pub enum Punctuator {
  Bang,
  Dollar,
  LeftParen,
  RightParen,
  Spread,
  Colon,
  Equals,
  At,
  LeftBracket,
  RightBracket,
  LeftBrace,
  RightBrace,
  Pipe,
}

pub struct Lexer<'a> {
  input: &'a str,
  iter: Peekable<CharIndices<'a>>,
  eof_emmited: bool,
  lo: usize,
  hi: usize,
}

impl<'a> Lexer<'a> {
  pub fn new(input: &'a str) -> Lexer<'a> {
    Lexer {
      input: input,
      iter: input.char_indices().peekable(),
      eof_emmited: false,
      lo: 0,
      hi: 0,
    }
  }
}

impl<'a> Iterator for Lexer<'a> {
  type Item = Result<Token<'a>>;
  fn next(&mut self) -> Option<Result<Token<'a>>> {
    if self.eof_emmited {
      None
    } else if self.iter.peek().is_none() {
      self.eof_emmited = true;
      Some(Ok(Token::Eof))
    } else {
      skip_ignored_token(self);
      let &(p, c) = self.iter.peek().unwrap();
      self.lo = p;
      Some(match c {
        '!' => punctuator!(self, Bang),
        '$' => punctuator!(self, Dollar),
        '(' => punctuator!(self, LeftParen),
        ')' => punctuator!(self, RightParen),
        ':' => punctuator!(self, Colon),
        '=' => punctuator!(self, Equals),
        '@' => punctuator!(self, At),
        '[' => punctuator!(self, LeftBracket),
        ']' => punctuator!(self, RightBracket),
        '{' => punctuator!(self, LeftBrace),
        '}' => punctuator!(self, RightBrace),
        '|' => punctuator!(self, Pipe),
        '.' => scan_spread(self),
        '_' | 'a'...'z' | 'A'...'Z' => scan_name(self),
        '-' | '0'...'9' => scan_number(self),
        '"' => scan_string(self),
        _ => Err(Error::UnxepectedChar),
      })
    }
  }
}

fn skip_ignored_token(lexer: &mut Lexer) {
  loop {
    if take!(lexer, '#') {
      take_while_not!(lexer, '\r' | '\n');
    }
    if !take_while!(lexer, '\u{feff}' | ' ' | '\t' | '\r' | '\n' | ',') {
      break;
    }
  }
}

fn scan_spread<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  if take!(lexer, '.') && take!(lexer, '.') && take!(lexer, '.') {
    Ok(Token::Punctuator(Punctuator::Spread, lexer.lo, lexer.hi))
  } else {
    Err(Error::UnxepectedChar)
  }
}

fn scan_name<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  take_while!(lexer, '_' | 'a'...'z' | 'A'...'Z' | '0'...'9');
  Ok(Token::Name(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi))
}

fn scan_number<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  take!(lexer, '+' | '-');
  // Integer part
  if take!(lexer, '1'...'9') {
    take_while!(lexer, '0'...'9');
    if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
      return Ok(Token::IntValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
    }
  } else if take!(lexer, '0') {
    if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
      return Ok(Token::IntValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
    }
  }
  if !peek!(lexer, '.' | 'E' | 'e') {
    return Err(Error::InvalidInt);
  }
  // Fractional part
  if take!(lexer, '.') {
    if !take_while!(lexer, '0'...'9') {
      return Err(Error::InvalidFloat);
    }
  }
  // Exponent part
  if take!(lexer, 'E' | 'e') {
    take!(lexer, '+' | '-');
    if !take_while!(lexer, '0'...'9') {
      return Err(Error::InvalidFloat);
    }
  }
  if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
    return Ok(Token::FloatValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
  }
  Err(Error::InvalidFloat)
}

fn scan_string<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  if take!(lexer, '"') {
    lexer.lo += 1;
  }
  loop {
    if take!(lexer, '\\') {
      if !take!(lexer, '\\' | '"' | 'b' | 'f' | 'n' | 'r' | 't' | '/' | 'u') {
        return Err(Error::BadEscape);
      }
    }
    if !take_while_not!(lexer, '"' | '\\' | '\r' | '\n') && !peek!(lexer, '"' | '\\') {
      return Err(Error::UnterminatedString);
    }
    if peek!(lexer, '\r' | '\n') {
      return Err(Error::UnterminatedString);
    }
    if peek!(lexer, '"') {
      lexer.iter.next();
      let s = try!(unexcape_str(&lexer.input[lexer.lo..lexer.hi]));
      return Ok(Token::StringValue(s, lexer.lo, lexer.hi));
    }
  }
}

fn unexcape_str(s: &str) -> Result<String> {
  let mut buf = String::with_capacity(s.len());
  let mut p = s.chars().peekable();
  while let Some(c) = p.next() {
    match c {
      '\\' => {
        match p.next() {
          Some('\\') => buf.push('\\'),
          Some('/') => buf.push('/'),
          Some('"') => buf.push('"'),
          Some('n') => buf.push('\n'),
          Some('r') => buf.push('\r'),
          Some('t') => buf.push('\t'),
          Some('b') => buf.push('\x08'),
          Some('f') => buf.push('\x0c'),
          Some('u') => {
            let u1 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u2 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u3 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u4 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let s = try!(u32::from_str_radix(format!("{}{}{}{}", u1, u2, u3, u4).as_ref(), 16)
              .or(Err(Error::BadUnicodeEscape)));
            let ch = try!(::std::char::from_u32(s).ok_or(Error::InvalidUtfChar));
            buf.push(ch);
          }
          _ => return Err(Error::UnxepectedChar),
        }
      }
      _ => buf.push(c),
    }
  }
  Ok(buf)
}
<commit_msg>fix scan_number not to accept leading '+'<commit_after>use std::str::CharIndices;
use std::iter::Peekable;
use std::result;

#[cfg(test)]
mod tests;

#[macro_use]
mod macros;

mod error;
pub use self::error::Error;
pub type Result<T> = result::Result<T, Error>;

#[derive(PartialEq, Debug)]
pub enum Token<'a> {
  Eof,
  Punctuator(Punctuator, usize, usize),
  Name(&'a str, usize, usize),
  IntValue(&'a str, usize, usize),
  FloatValue(&'a str, usize, usize),
  StringValue(String, usize, usize),
}

#[derive(PartialEq, Debug)]
pub enum Punctuator {
  Bang,
  Dollar,
  LeftParen,
  RightParen,
  Spread,
  Colon,
  Equals,
  At,
  LeftBracket,
  RightBracket,
  LeftBrace,
  RightBrace,
  Pipe,
}

pub struct Lexer<'a> {
  input: &'a str,
  iter: Peekable<CharIndices<'a>>,
  eof_emmited: bool,
  lo: usize,
  hi: usize,
}

impl<'a> Lexer<'a> {
  pub fn new(input: &'a str) -> Lexer<'a> {
    Lexer {
      input: input,
      iter: input.char_indices().peekable(),
      eof_emmited: false,
      lo: 0,
      hi: 0,
    }
  }
}

impl<'a> Iterator for Lexer<'a> {
  type Item = Result<Token<'a>>;
  fn next(&mut self) -> Option<Result<Token<'a>>> {
    if self.eof_emmited {
      None
    } else if self.iter.peek().is_none() {
      self.eof_emmited = true;
      Some(Ok(Token::Eof))
    } else {
      skip_ignored_token(self);
      let &(p, c) = self.iter.peek().unwrap();
      self.lo = p;
      Some(match c {
        '!' => punctuator!(self, Bang),
        '$' => punctuator!(self, Dollar),
        '(' => punctuator!(self, LeftParen),
        ')' => punctuator!(self, RightParen),
        ':' => punctuator!(self, Colon),
        '=' => punctuator!(self, Equals),
        '@' => punctuator!(self, At),
        '[' => punctuator!(self, LeftBracket),
        ']' => punctuator!(self, RightBracket),
        '{' => punctuator!(self, LeftBrace),
        '}' => punctuator!(self, RightBrace),
        '|' => punctuator!(self, Pipe),
        '.' => scan_spread(self),
        '_' | 'a'...'z' | 'A'...'Z' => scan_name(self),
        '-' | '0'...'9' => scan_number(self),
        '"' => scan_string(self),
        _ => Err(Error::UnxepectedChar),
      })
    }
  }
}

fn skip_ignored_token(lexer: &mut Lexer) {
  loop {
    if take!(lexer, '#') {
      take_while_not!(lexer, '\r' | '\n');
    }
    if !take_while!(lexer, '\u{feff}' | ' ' | '\t' | '\r' | '\n' | ',') {
      break;
    }
  }
}

fn scan_spread<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  if take!(lexer, '.') && take!(lexer, '.') && take!(lexer, '.') {
    Ok(Token::Punctuator(Punctuator::Spread, lexer.lo, lexer.hi))
  } else {
    Err(Error::UnxepectedChar)
  }
}

fn scan_name<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  take_while!(lexer, '_' | 'a'...'z' | 'A'...'Z' | '0'...'9');
  Ok(Token::Name(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi))
}

fn scan_number<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  take!(lexer, '-');
  // Integer part
  if take!(lexer, '1'...'9') {
    take_while!(lexer, '0'...'9');
    if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
      return Ok(Token::IntValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
    }
  } else if take!(lexer, '0') {
    if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
      return Ok(Token::IntValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
    }
  }
  if !peek!(lexer, '.' | 'E' | 'e') {
    return Err(Error::InvalidInt);
  }
  // Fractional part
  if take!(lexer, '.') {
    if !take_while!(lexer, '0'...'9') {
      return Err(Error::InvalidFloat);
    }
  }
  // Exponent part
  if take!(lexer, 'E' | 'e') {
    take!(lexer, '+' | '-');
    if !take_while!(lexer, '0'...'9') {
      return Err(Error::InvalidFloat);
    }
  }
  if follow_by!(lexer, ' ' | '\t' | '\r' | '\n' | ',') || lexer.iter.peek().is_none() {
    return Ok(Token::FloatValue(&lexer.input[lexer.lo..lexer.hi], lexer.lo, lexer.hi));
  }
  Err(Error::InvalidFloat)
}

fn scan_string<'a>(lexer: &mut Lexer<'a>) -> Result<Token<'a>> {
  if take!(lexer, '"') {
    lexer.lo += 1;
  }
  loop {
    if take!(lexer, '\\') {
      if !take!(lexer, '\\' | '"' | 'b' | 'f' | 'n' | 'r' | 't' | '/' | 'u') {
        return Err(Error::BadEscape);
      }
    }
    if !take_while_not!(lexer, '"' | '\\' | '\r' | '\n') && !peek!(lexer, '"' | '\\') {
      return Err(Error::UnterminatedString);
    }
    if peek!(lexer, '\r' | '\n') {
      return Err(Error::UnterminatedString);
    }
    if peek!(lexer, '"') {
      lexer.iter.next();
      let s = try!(unexcape_str(&lexer.input[lexer.lo..lexer.hi]));
      return Ok(Token::StringValue(s, lexer.lo, lexer.hi));
    }
  }
}

fn unexcape_str(s: &str) -> Result<String> {
  let mut buf = String::with_capacity(s.len());
  let mut p = s.chars().peekable();
  while let Some(c) = p.next() {
    match c {
      '\\' => {
        match p.next() {
          Some('\\') => buf.push('\\'),
          Some('/') => buf.push('/'),
          Some('"') => buf.push('"'),
          Some('n') => buf.push('\n'),
          Some('r') => buf.push('\r'),
          Some('t') => buf.push('\t'),
          Some('b') => buf.push('\x08'),
          Some('f') => buf.push('\x0c'),
          Some('u') => {
            let u1 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u2 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u3 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let u4 = try!(p.next().ok_or(Error::BadUnicodeEscape));
            let s = try!(u32::from_str_radix(format!("{}{}{}{}", u1, u2, u3, u4).as_ref(), 16)
              .or(Err(Error::BadUnicodeEscape)));
            let ch = try!(::std::char::from_u32(s).ok_or(Error::InvalidUtfChar));
            buf.push(ch);
          }
          _ => return Err(Error::UnxepectedChar),
        }
      }
      _ => buf.push(c),
    }
  }
  Ok(buf)
}
<|endoftext|>


<commit_before>#[derive(Debug)]
pub enum HammingError {
    FirstLonger,
    SecondLonger,
}

pub fn hamming_distance(a: &str, b: &str) -> Result<u64, HammingError> {
    if a.len() > b.len() {
        Err(HammingError::FirstLonger)
    } else if a.len() < b.len() {
        Err(HammingError::SecondLonger)
    } else {
        Ok(a.chars()
            .zip(b.chars())
            .fold(0, |z, (x, y)| acc + (if x == y { 0 } else { 1 })))
    }
}
<commit_msg>clippy<commit_after>#[derive(Debug)]
pub enum HammingError {
    FirstLonger,
    SecondLonger,
}

pub fn hamming_distance(a: &str, b: &str) -> Result<u64, HammingError> {
    if a.len() > b.len() {
        Err(HammingError::FirstLonger)
    } else if a.len() < b.len() {
        Err(HammingError::SecondLonger)
    } else {
        Ok(a.chars()
            .zip(b.chars())
            .fold(0, |z, (x, y)| z + (if x == y { 0 } else { 1 })))
    }
}
<|endoftext|>


<commit_before>use serde_json::Value;
use iron::Handler;
use mount::Mount;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{View, Error as StorageError};
use messages::{Message, RawTransaction};
use encoding::Error as MessageError;
use node::{Node, State, NodeChannel, TxSender};
use node::state::ValidatorState;
use blockchain::{ConsensusConfig, Blockchain};

pub trait Transaction: Message + 'static {
    fn verify(&self) -> bool;
    fn execute(&self, view: &View) -> Result<(), StorageError>;
    fn info(&self) -> Value {
        Value::Null
    }
}

#[allow(unused_variables, unused_mut)]
pub trait Service: Send + Sync + 'static {
    /// Unique service identification for database schema and service messages.
    fn service_id(&self) -> u16;
    /// Unique human readable service name.
    fn service_name(&self) -> &'static str;

    fn state_hash(&self, _: &View) -> Result<Vec<Hash>, StorageError> {
        Ok(Vec::new())
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    fn handle_genesis_block(&self, view: &View) -> Result<Value, StorageError> {
        Ok(Value::Null)
    }

    fn handle_commit(&self, context: &mut ServiceContext) -> Result<(), StorageError> {
        Ok(())
    }
    /// Returns api handler for public users.
    fn public_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
    /// Returns api handler for maintainers.
    fn private_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
}

#[derive(Debug)]
pub struct ServiceContext<'a, 'b> {
    state: &'a mut State,
    view: &'b View,
    txs: Vec<Box<Transaction>>,
}

impl<'a, 'b> ServiceContext<'a, 'b> {
    pub fn new(state: &'a mut State, view: &'b View) -> ServiceContext<'a, 'b> {
        ServiceContext {
            state: state,
            view: view,
            txs: Vec::new(),
        }
    }

    pub fn validator_state(&self) -> &Option<ValidatorState> {
        self.state.validator_state()
    }

    pub fn view(&self) -> &View {
        self.view
    }

    pub fn height(&self) -> u64 {
        self.state.height()
    }

    pub fn round(&self) -> u32 {
        self.state.round()
    }

    pub fn validators(&self) -> &[PublicKey] {
        self.state.validators()
    }

    pub fn public_key(&self) -> &PublicKey {
        self.state.public_key()
    }

    pub fn secret_key(&self) -> &SecretKey {
        self.state.secret_key()
    }

    pub fn actual_consensus_config(&self) -> &ConsensusConfig {
        self.state.consensus_config()
    }

    pub fn actual_service_config(&self, service: &Service) -> &Value {
        let name = service.service_name();
        self.state.services_config().get(name).unwrap()
    }

    pub fn add_transaction<T: Transaction>(&mut self, tx: T) {
        assert!(tx.verify());
        self.txs.push(Box::new(tx));
    }

    pub fn transactions(self) -> Vec<Box<Transaction>> {
        self.txs
    }
}

#[derive(Debug)]
pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: TxSender<NodeChannel>,
    public_key: PublicKey,
    secret_key: SecretKey,
}

impl ApiContext {
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: *node.state().public_key(),
            secret_key: node.state().secret_key().clone(),
        }
    }

    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    pub fn node_channel(&self) -> &TxSender<NodeChannel> {
        &self.node_channel
    }

    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }

    pub fn mount_public_api(&self) -> Mount {
        self.blockchain.mount_public_api(self)
    }

    pub fn mount_private_api(&self) -> Mount {
        self.blockchain.mount_private_api(self)
    }
}<commit_msg>Update 'Service' interface<commit_after>use serde_json::Value;
use iron::Handler;
use mount::Mount;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{View, Error as StorageError};
use messages::{Message, RawTransaction};
use encoding::Error as MessageError;
use node::{Node, State, NodeChannel, TxSender};
use node::state::ValidatorState;
use blockchain::{ConsensusConfig, Blockchain};

pub trait Transaction: Message + 'static {
    fn verify(&self) -> bool;
    fn execute(&self, view: &View) -> Result<(), StorageError>;
    fn info(&self) -> Value {
        Value::Null
    }
}

#[allow(unused_variables, unused_mut)]
pub trait Service: Send + Sync + 'static {
    /// Unique service identification for database schema and service messages.
    fn service_id(&self) -> u16;
    /// Unique human readable service name.
    fn service_name(&self) -> &'static str;

    fn state_hash(&self, _: &View) -> Result<Vec<Hash>, StorageError> {
        Ok(Vec::new())
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    fn handle_genesis_block(&self, view: &View) -> Result<Value, StorageError> {
        Ok(Value::Null)
    }

    fn handle_commit(&self, context: &mut ServiceContext) -> Result<(), StorageError> {
        Ok(())
    }
    /// Returns api handler for public users.
    fn public_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
    /// Returns api handler for maintainers.
    fn private_api_handler(&self, context: &ApiContext) -> Option<Box<Handler>> {
        None
    }
}

#[derive(Debug)]
pub struct ServiceContext<'a, 'b> {
    state: &'a mut State,
    view: &'b View,
    txs: Vec<Box<Transaction>>,
}

impl<'a, 'b> ServiceContext<'a, 'b> {
    pub fn new(state: &'a mut State, view: &'b View) -> ServiceContext<'a, 'b> {
        ServiceContext {
            state: state,
            view: view,
            txs: Vec::new(),
        }
    }

    pub fn validator_state(&self) -> &Option<ValidatorState> {
        self.state.validator_state()
    }

    pub fn view(&self) -> &View {
        self.view
    }

    pub fn height(&self) -> u64 {
        self.state.height()
    }

    pub fn round(&self) -> u32 {
        self.state.round()
    }

    pub fn validators(&self) -> &[PublicKey] {
        self.state.validators()
    }

    pub fn public_key(&self) -> &PublicKey {
        self.state.public_key()
    }

    pub fn secret_key(&self) -> &SecretKey {
        self.state.secret_key()
    }

    pub fn actual_consensus_config(&self) -> &ConsensusConfig {
        self.state.consensus_config()
    }

    pub fn actual_service_config(&self, service: &Service) -> &Value {
        let name = service.service_name();
        self.state.services_config().get(name).unwrap()
    }

    pub fn add_transaction(&mut self, tx: Box<Transaction>) {
        assert!(tx.verify());
        self.txs.push(tx);
    }

    pub fn transactions(self) -> Vec<Box<Transaction>> {
        self.txs
    }
}

#[derive(Debug)]
pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: TxSender<NodeChannel>,
    public_key: PublicKey,
    secret_key: SecretKey,
}

impl ApiContext {
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: *node.state().public_key(),
            secret_key: node.state().secret_key().clone(),
        }
    }

    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    pub fn node_channel(&self) -> &TxSender<NodeChannel> {
        &self.node_channel
    }

    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }

    pub fn mount_public_api(&self) -> Mount {
        self.blockchain.mount_public_api(self)
    }

    pub fn mount_private_api(&self) -> Mount {
        self.blockchain.mount_private_api(self)
    }
}<|endoftext|>


<commit_before>//! # The implementation of librsvg
//!
//! The implementation of librsvg is in the `rsvg_internals` crate.  It is not a public
//! crate; instead, it exports the primitives necessary to implement librsvg's public APIs,
//! both the C and Rust APIs.  It has the XML and CSS parsing code, the SVG element
//! definitions and tree of elements, and all the drawing logic.
//!
//! Some interesting parts of rsvg_internals:
//!
//! * [The `Handle` struct](handle/struct.Handle.html) provides the primitives to implement
//! the public APIs, such as loading an SVG file and rendering it.
//!
//! * [The `DrawingCtx` struct](drawing_ctx/struct.DrawingCtx.html) is active while an SVG
//! handle is being drawn or queried for its geometry.  It has all the mutable state related
//! to the drawing process.
//!
//! * [The `Document` struct](document/struct.Document.html) represents a loaded SVG
//! document.  It holds the tree of [`Node`] elements, and a mapping of `id` attributes
//! to the corresponding element nodes.
//!
//! * [The `node` module](node/index.html) provides the [`Node`] struct and
//! helper traits used to operate on nodes.
//!
//! * [The `element` module](element/index.html) provides the [`Element`] struct and
//! the [`SetAttributes`] and [`Draw`] traits which are implemented by all SVG elements.
//!
//! * [The `xml` module](xml/index.html) receives events from the XML parser, and builds a
//! [`Document`] as a tree of [`Node`].
//!
//! * [The `properties` module](properties/index.html) contains structs that represent
//! collections of CSS properties.
//!
//! * [The `property_defs` module](property_defs/index.html) contains one type for each of
//! the CSS style properties that librsvg supports.
//!
//! * [The `css` module](css/index.html) contains the implementation of CSS parsing
//! and matching.
//!
//! [`Document`]: document/struct.Document.html
//! [`Node`]: node/type.Node.html
//! [`Element`]: element/struct.Element.html
//! [`SetAttributes`]: element/trait.SetAttributes.html
//! [`Draw`]: element/trait.Draw.html

#![allow(clippy::clone_on_ref_ptr)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
#![allow(clippy::too_many_arguments)]
#![warn(unused)]

pub use crate::color::Color;

pub use crate::dpi::Dpi;

pub use crate::error::{DefsLookupErrorKind, HrefError, LoadingError, RenderingError};

pub use crate::handle::{Handle, LoadOptions};

pub use crate::length::{Length, LengthUnit, RsvgLength};

pub use crate::parsers::Parse;

pub use crate::rect::{IRect, Rect};

pub use crate::structure::IntrinsicDimensions;

pub use crate::surface_utils::{
    iterators::Pixels,
    shared_surface::{SharedImageSurface, SurfaceType},
    CairoARGB, Pixel,
};

pub use crate::viewbox::ViewBox;

#[macro_use]
pub mod log;

#[macro_use]
mod parsers;

#[macro_use]
mod coord_units;

#[macro_use]
mod float_eq_cairo;

#[macro_use]
mod node;

#[macro_use]
mod property_macros;

mod allowed_url;
mod angle;
mod aspect_ratio;
mod bbox;
mod color;
mod cond;
mod css;
mod dasharray;
mod document;
mod dpi;
mod drawing_ctx;
mod element;
mod error;
mod filter;
pub mod filters;
mod font_props;
mod gradient;
mod handle;
mod href;
mod image;
mod io;
mod iri;
mod length;
mod limits;
mod marker;
mod number_list;
mod paint_server;
pub mod path_builder; // pub for benchmarking
pub mod path_parser; // pub for benchmarking
mod pattern;
mod properties;
mod property_bag;
mod property_defs;
pub mod rect;
mod shapes;
mod space;
mod structure;
mod style;
pub mod surface_utils;
mod text;
mod transform;
mod unit_interval;
mod util;
mod viewbox;
mod xml;
mod xml2;
mod xml2_load;
<commit_msg>More pointers for newcomers<commit_after>//! The implementation of librsvg.
//!
//! The implementation of librsvg is in the `rsvg_internals` crate.  It is not a public
//! crate; instead, it exports the primitives necessary to implement librsvg's public APIs,
//! both the C and Rust APIs.  It has the XML and CSS parsing code, the SVG element
//! definitions and tree of elements, and all the drawing logic.
//!
//! # Common entry points for newcomers
//!
//! * Are you adding support for a CSS property?  Look in the [`property_defs`] module.
//!
//! # Some interesting parts of rsvg_internals
//!
//! * The [`Handle`] struct provides the primitives to implement the public APIs, such as
//! loading an SVG file and rendering it.
//!
//! * The [`DrawingCtx`] struct is active while an SVG handle is being drawn or queried
//! for its geometry.  It has all the mutable state related to the drawing process.
//!
//! * The [`Document`] struct represents a loaded SVG document.  It holds the tree of
//! [`Node`] elements, and a mapping of `id` attributes to the corresponding element
//! nodes.
//!
//! * The [`node`] module provides the [`Node`] struct and helper traits used to operate
//! on nodes.
//!
//! * The [`element`] module provides the [`Element`] struct and the [`SetAttributes`] and
//! [`Draw`] traits which are implemented by all SVG elements.
//!
//! * The [`xml`] module receives events from the XML parser, and builds a [`Document`] as
//! a tree of [`Node`].
//!
//! * The [`properties`] module contains structs that represent collections of CSS
//! properties.
//!
//! * The [`property_defs`] module contains one type for each of the CSS style properties
//! that librsvg supports.
//!
//! * The [`css`] module contains the implementation of CSS parsing and matching.
//!
//! [`Document`]: document/struct.Document.html
//! [`Node`]: node/type.Node.html
//! [`Element`]: element/struct.Element.html
//! [`Handle`]: handle/struct.Handle.html
//! [`DrawingCtx`]: drawing_ctx/struct.DrawingCtx.html
//! [`Document`]: document/struct.Document.html
//! [`SetAttributes`]: element/trait.SetAttributes.html
//! [`Draw`]: element/trait.Draw.html
//! [`css`]: css/index.html
//! [`element`]: element/index.html
//! [`node`]: node/index.html
//! [`properties`]: properties/index.html
//! [`property_defs`]: property_defs/index.html
//! [`xml`]: xml/index.html

#![allow(clippy::clone_on_ref_ptr)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
#![allow(clippy::too_many_arguments)]
#![warn(unused)]

pub use crate::color::Color;

pub use crate::dpi::Dpi;

pub use crate::error::{DefsLookupErrorKind, HrefError, LoadingError, RenderingError};

pub use crate::handle::{Handle, LoadOptions};

pub use crate::length::{Length, LengthUnit, RsvgLength};

pub use crate::parsers::Parse;

pub use crate::rect::{IRect, Rect};

pub use crate::structure::IntrinsicDimensions;

pub use crate::surface_utils::{
    iterators::Pixels,
    shared_surface::{SharedImageSurface, SurfaceType},
    CairoARGB, Pixel,
};

pub use crate::viewbox::ViewBox;

#[macro_use]
pub mod log;

#[macro_use]
mod parsers;

#[macro_use]
mod coord_units;

#[macro_use]
mod float_eq_cairo;

#[macro_use]
mod node;

#[macro_use]
mod property_macros;

mod allowed_url;
mod angle;
mod aspect_ratio;
mod bbox;
mod color;
mod cond;
mod css;
mod dasharray;
mod document;
mod dpi;
mod drawing_ctx;
mod element;
mod error;
mod filter;
pub mod filters;
mod font_props;
mod gradient;
mod handle;
mod href;
mod image;
mod io;
mod iri;
mod length;
mod limits;
mod marker;
mod number_list;
mod paint_server;
pub mod path_builder; // pub for benchmarking
pub mod path_parser; // pub for benchmarking
mod pattern;
mod properties;
mod property_bag;
mod property_defs;
pub mod rect;
mod shapes;
mod space;
mod structure;
mod style;
pub mod surface_utils;
mod text;
mod transform;
mod unit_interval;
mod util;
mod viewbox;
mod xml;
mod xml2;
mod xml2_load;
<|endoftext|>


<commit_before>use std::{collections::BTreeMap, convert::TryInto, fmt};

use js_int::Int;
use serde::{
    de::{self, Deserializer, IntoDeserializer as _, Visitor},
    Deserialize,
};

/// Serde deserialization decorator to map empty Strings to None,
/// and forward non-empty Strings to the Deserialize implementation for T.
/// Useful for the typical
/// "A room with an X event with an absent, null, or empty Y field
/// should be treated the same as a room with no such event."
/// formulation in the spec.
///
/// To be used like this:
/// `#[serde(deserialize_with = "empty_string_as_none")]`
/// Relevant serde issue: <https://github.com/serde-rs/serde/issues/1425>
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de>,
{
    let opt = Option::<String>::deserialize(de)?;
    match opt.as_deref() {
        None | Some("") => Ok(None),
        // If T = String, like in m.room.name, the second deserialize is actually superfluous.
        // TODO: optimize that somehow?
        Some(s) => T::deserialize(s.into_deserializer()).map(Some),
    }
}

/// Take either an integer number or a string and deserialize to an integer number.
///
/// To be used like this:
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
where
    D: Deserializer<'de>,
{
    struct IntOrStringVisitor;

    impl<'de> Visitor<'de> for IntOrStringVisitor {
        type Value = Int;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("an integer or a string")
        }

        fn visit_i8<E: de::Error>(self, v: i8) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i16<E: de::Error>(self, v: i16) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i32<E: de::Error>(self, v: i32) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_i128<E: de::Error>(self, v: i128) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_u8<E: de::Error>(self, v: u8) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u16<E: de::Error>(self, v: u16) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u32<E: de::Error>(self, v: u32) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_u128<E: de::Error>(self, v: u128) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
            v.parse().map_err(E::custom)
        }
    }

    de.deserialize_any(IntOrStringVisitor)
}

/// Take a BTreeMap with values of either an integer number or a string and deserialize
/// those to integer numbers.
///
/// To be used like this:
/// `#[serde(deserialize_with = "btreemap_int_or_string_to_int_values")]`
pub fn btreemap_int_or_string_to_int_values<'de, D, T>(de: D) -> Result<BTreeMap<T, Int>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de> + Ord,
{
    #[repr(transparent)]
    struct IntWrap(Int);

    impl<'de> Deserialize<'de> for IntWrap {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            int_or_string_to_int(deserializer).map(IntWrap)
        }
    }

    Ok(BTreeMap::<T, IntWrap>::deserialize(de)?.into_iter().map(|(k, IntWrap(v))| (k, v)).collect())
}

#[cfg(test)]
mod tests {
    use js_int::{int, Int};
    use matches::assert_matches;
    use serde::Deserialize;

    use super::int_or_string_to_int;

    #[test]
    fn int_or_string() -> Result<(), serde_json::Error> {
        #[derive(Debug, Deserialize)]
        struct Test {
            #[serde(deserialize_with = "int_or_string_to_int")]
            num: Int,
        }

        assert_matches!(
            serde_json::from_value::<Test>(serde_json::json!({ "num": "0" }))?,
            Test { num } if num == int!(0)
        );

        Ok(())
    }
}
<commit_msg>serde: Optimize btreemap_int_or_string_to_int_values<commit_after>use std::{collections::BTreeMap, convert::TryInto, fmt, marker::PhantomData};

use js_int::Int;
use serde::{
    de::{self, Deserializer, IntoDeserializer as _, MapAccess, Visitor},
    Deserialize,
};

/// Serde deserialization decorator to map empty Strings to None,
/// and forward non-empty Strings to the Deserialize implementation for T.
/// Useful for the typical
/// "A room with an X event with an absent, null, or empty Y field
/// should be treated the same as a room with no such event."
/// formulation in the spec.
///
/// To be used like this:
/// `#[serde(deserialize_with = "empty_string_as_none")]`
/// Relevant serde issue: <https://github.com/serde-rs/serde/issues/1425>
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de>,
{
    let opt = Option::<String>::deserialize(de)?;
    match opt.as_deref() {
        None | Some("") => Ok(None),
        // If T = String, like in m.room.name, the second deserialize is actually superfluous.
        // TODO: optimize that somehow?
        Some(s) => T::deserialize(s.into_deserializer()).map(Some),
    }
}

/// Take either an integer number or a string and deserialize to an integer number.
///
/// To be used like this:
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
where
    D: Deserializer<'de>,
{
    struct IntOrStringVisitor;

    impl<'de> Visitor<'de> for IntOrStringVisitor {
        type Value = Int;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("an integer or a string")
        }

        fn visit_i8<E: de::Error>(self, v: i8) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i16<E: de::Error>(self, v: i16) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i32<E: de::Error>(self, v: i32) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_i128<E: de::Error>(self, v: i128) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_u8<E: de::Error>(self, v: u8) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u16<E: de::Error>(self, v: u16) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u32<E: de::Error>(self, v: u32) -> Result<Self::Value, E> {
            Ok(v.into())
        }

        fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_u128<E: de::Error>(self, v: u128) -> Result<Self::Value, E> {
            v.try_into().map_err(E::custom)
        }

        fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
            v.parse().map_err(E::custom)
        }
    }

    de.deserialize_any(IntOrStringVisitor)
}

/// Take a BTreeMap with values of either an integer number or a string and deserialize
/// those to integer numbers.
///
/// To be used like this:
/// `#[serde(deserialize_with = "btreemap_int_or_string_to_int_values")]`
pub fn btreemap_int_or_string_to_int_values<'de, D, T>(de: D) -> Result<BTreeMap<T, Int>, D::Error>
where
    D: Deserializer<'de>,
    T: Deserialize<'de> + Ord,
{
    #[repr(transparent)]
    struct IntWrap(Int);

    impl<'de> Deserialize<'de> for IntWrap {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            int_or_string_to_int(deserializer).map(IntWrap)
        }
    }

    struct IntMapVisitor<T> {
        _phantom: PhantomData<T>,
    }

    impl<T> IntMapVisitor<T> {
        fn new() -> Self {
            Self { _phantom: PhantomData }
        }
    }

    impl<'de, T> Visitor<'de> for IntMapVisitor<T>
    where
        T: Deserialize<'de> + Ord,
    {
        type Value = BTreeMap<T, Int>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a map with integers or stings as values")
        }

        fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
            let mut res = BTreeMap::new();

            while let Some((k, IntWrap(v))) = map.next_entry()? {
                res.insert(k, v);
            }

            Ok(res)
        }
    }

    de.deserialize_map(IntMapVisitor::new())
}

#[cfg(test)]
mod tests {
    use js_int::{int, Int};
    use matches::assert_matches;
    use serde::Deserialize;

    use super::int_or_string_to_int;

    #[test]
    fn int_or_string() -> Result<(), serde_json::Error> {
        #[derive(Debug, Deserialize)]
        struct Test {
            #[serde(deserialize_with = "int_or_string_to_int")]
            num: Int,
        }

        assert_matches!(
            serde_json::from_value::<Test>(serde_json::json!({ "num": "0" }))?,
            Test { num } if num == int!(0)
        );

        Ok(())
    }
}
<|endoftext|>


<commit_before>use na::RealField;

use crate::utils::IsometryOps;
use crate::math::{Isometry, Vector, Rotation};

/// A continuous interpolation of isometries.
pub trait RigidMotion<N: RealField> {
    /// Get a position at the time `t`.
    fn position_at_time(&self, t: N) -> Isometry<N>;
}

/// Interpolation between two isometries using LERP for the translation part and SLERP for the rotation.
pub struct InterpolatedRigidMotion<'a, N: RealField> {
    /// The transformation at `t = 0.0`.
    pub start: &'a Isometry<N>,
    /// The transformation at `t = 1.0`.
    pub end: &'a Isometry<N>,
}

impl<'a, N: RealField> InterpolatedRigidMotion<'a, N> {
    /// Initialize a lerp-slerp interpolation with the given start and end transformations.
    ///
    /// The `start` is the transformation at the time `t = 0.0` and `end` is the transformation at
    /// the time `t = 1.0`.
    pub fn new(start: &'a Isometry<N>, end: &'a Isometry<N>) -> Self {
        InterpolatedRigidMotion {
            start, end
        }
    }
}

impl<'a, N: RealField> RigidMotion<N> for InterpolatedRigidMotion<'a, N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        self.start.lerp_slerp(self.end, t)
    }
}

/// A linear motion from a starting isometry traveling at constant translational velocity.
pub struct ConstantLinearVelocityRigidMotion<'a, N: RealField> {
    /// The starting isometry at `t = 0`.
    pub start: &'a Isometry<N>,
    /// The translational velocity of this motion.
    pub velocity: Vector<N>,
}

impl<'a, N: RealField> ConstantLinearVelocityRigidMotion<'a, N> {
    /// Initialize a linear motion frow a starting isometry and a translational velocity.
    pub fn new(start: &'a Isometry<N>, velocity: Vector<N>) -> Self {
        ConstantLinearVelocityRigidMotion {
            start, velocity
        }
    }
}

impl<'a, N: RealField> RigidMotion<N> for ConstantLinearVelocityRigidMotion<'a, N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        Isometry::from_parts(
            (self.start.translation.vector + self.velocity * t).into(),
            self.start.rotation
        )
    }
}

/// A linear motion from a starting isometry traveling at constant translational velocity.
pub struct ConstantVelocityRigidMotion<'a, N: RealField> {
    /// The time at which this parametrization begins. Can be negative.
    pub t0: N,
    /// The starting isometry at `t = self.start_t`.
    pub start: &'a Isometry<N>,
    /// The translational velocity of this motion.
    pub linvel: Vector<N>,
    /// The angular velocity of this motion.
    #[cfg(feature = "dim2")]
    pub angvel: N,
    /// The angular velocity of this motion.
    #[cfg(feature = "dim3")]
    pub angvel: Vector<N>,

}

impl<'a, N: RealField> ConstantVelocityRigidMotion<'a, N> {
    /// Initialize a motion from a starting isometry and linear and angular velocities.
    #[cfg(feature = "dim2")]
    pub fn new(t0: N, start: &'a Isometry<N>, linvel: Vector<N>, angvel: N) -> Self {
        ConstantVelocityRigidMotion {
            t0, start, linvel, angvel
        }
    }

    /// Initialize a motion from a starting isometry and linear and angular velocities.
    #[cfg(feature = "dim3")]
    pub fn new(t0: N, start: &'a Isometry<N>, linvel: Vector<N>, angvel: Vector<N>) -> Self {
        ConstantVelocityRigidMotion {
            t0, start, linvel, angvel
        }
    }
}

impl<'a, N: RealField> RigidMotion<N> for ConstantVelocityRigidMotion<'a, N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        Isometry::from_parts(
            (self.start.translation.vector + self.linvel * (t - self.t0)).into(),
            Rotation::new(self.angvel * (t - self.t0)) * self.start.rotation
        )
    }
}<commit_msg>Remove references from predefined rigid motion structures.<commit_after>use na::RealField;

use crate::utils::IsometryOps;
use crate::math::{Isometry, Vector, Rotation};

/// A continuous interpolation of isometries.
pub trait RigidMotion<N: RealField> {
    /// Get a position at the time `t`.
    fn position_at_time(&self, t: N) -> Isometry<N>;
}

/// Interpolation between two isometries using LERP for the translation part and SLERP for the rotation.
pub struct InterpolatedRigidMotion<N: RealField> {
    /// The transformation at `t = 0.0`.
    pub start: Isometry<N>,
    /// The transformation at `t = 1.0`.
    pub end: Isometry<N>,
}

impl<N: RealField> InterpolatedRigidMotion<N> {
    /// Initialize a lerp-slerp interpolation with the given start and end transformations.
    ///
    /// The `start` is the transformation at the time `t = 0.0` and `end` is the transformation at
    /// the time `t = 1.0`.
    pub fn new(start: Isometry<N>, end: Isometry<N>) -> Self {
        InterpolatedRigidMotion {
            start, end
        }
    }
}

impl<N: RealField> RigidMotion<N> for InterpolatedRigidMotion<N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        self.start.lerp_slerp(&self.end, t)
    }
}

/// A linear motion from a starting isometry traveling at constant translational velocity.
pub struct ConstantLinearVelocityRigidMotion<N: RealField> {
    /// The starting isometry at `t = 0`.
    pub start: Isometry<N>,
    /// The translational velocity of this motion.
    pub velocity: Vector<N>,
}

impl<N: RealField> ConstantLinearVelocityRigidMotion<N> {
    /// Initialize a linear motion frow a starting isometry and a translational velocity.
    pub fn new(start: Isometry<N>, velocity: Vector<N>) -> Self {
        ConstantLinearVelocityRigidMotion {
            start, velocity
        }
    }
}

impl<N: RealField> RigidMotion<N> for ConstantLinearVelocityRigidMotion<N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        Isometry::from_parts(
            (self.start.translation.vector + self.velocity * t).into(),
            self.start.rotation
        )
    }
}

/// A linear motion from a starting isometry traveling at constant translational velocity.
pub struct ConstantVelocityRigidMotion<N: RealField> {
    /// The time at which this parametrization begins. Can be negative.
    pub t0: N,
    /// The starting isometry at `t = self.start_t`.
    pub start: Isometry<N>,
    /// The translational velocity of this motion.
    pub linvel: Vector<N>,
    /// The angular velocity of this motion.
    #[cfg(feature = "dim2")]
    pub angvel: N,
    /// The angular velocity of this motion.
    #[cfg(feature = "dim3")]
    pub angvel: Vector<N>,

}

impl<N: RealField> ConstantVelocityRigidMotion<N> {
    /// Initialize a motion from a starting isometry and linear and angular velocities.
    #[cfg(feature = "dim2")]
    pub fn new(t0: N, start: Isometry<N>, linvel: Vector<N>, angvel: N) -> Self {
        ConstantVelocityRigidMotion {
            t0, start, linvel, angvel
        }
    }

    /// Initialize a motion from a starting isometry and linear and angular velocities.
    #[cfg(feature = "dim3")]
    pub fn new(t0: N, start: Isometry<N>, linvel: Vector<N>, angvel: Vector<N>) -> Self {
        ConstantVelocityRigidMotion {
            t0, start, linvel, angvel
        }
    }
}

impl<N: RealField> RigidMotion<N> for ConstantVelocityRigidMotion<N> {
    fn position_at_time(&self, t: N) -> Isometry<N> {
        Isometry::from_parts(
            (self.start.translation.vector + self.linvel * (t - self.t0)).into(),
            Rotation::new(self.angvel * (t - self.t0)) * self.start.rotation
        )
    }
}<|endoftext|>


<commit_before>//! Create new `Streams` connected to external inputs.

use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;

use progress::frontier::Antichain;
use progress::{Operate, Timestamp};
use progress::nested::subgraph::Source;
use progress::count_map::CountMap;
use progress::timestamp::RootTimestamp;
use progress::nested::product::Product;

use timely_communication::Allocate;
use {Data, Push};
use dataflow::channels::Content;
use dataflow::channels::pushers::{Tee, Counter};

use dataflow::{Stream, Scope};
use dataflow::scopes::{Child, Root};

// TODO : This is an exogenous input, but it would be nice to wrap a Subgraph in something
// TODO : more like a harness, with direct access to its inputs.

// NOTE : This only takes a &self, not a &mut self, which works but is a bit weird.
// NOTE : Experiments with &mut indicate that the borrow of 'a lives for too long.
// NOTE : Might be able to fix with another lifetime parameter, say 'c: 'a.

/// Create a new `Stream` and `Handle` through which to supply input.
pub trait Input<'a, A: Allocate, T: Timestamp+Ord> {
    /// Create a new `Stream` and `Handle` through which to supply input.
    ///
    /// The `new_input` method returns a pair `(Handle, Stream)` where the `Stream` can be used
    /// immediately for timely dataflow construction, and the `Handle` is later used to introduce
    /// data into the timely dataflow computation.
    ///
    /// The `Handle` also provides a means to indicate
    /// to timely dataflow that the input has advanced beyond certain timestamps, allowing timely
    /// to issue progress notifications.
    ///
    /// #Examples
    /// ```
    /// use timely::*;
    /// use timely::dataflow::operators::{Input, Inspect};
    ///
    /// // construct and execute a timely dataflow
    /// timely::execute(Configuration::Thread, |worker| {
    ///
    ///     // add an input and base computation off of it
    ///     let mut input = worker.dataflow(|scope| {
    ///         let (input, stream) = scope.new_input();
    ///         stream.inspect(|x| println!("hello {:?}", x));
    ///         input
    ///     });
    ///
    ///     // introduce input, advance computation
    ///     for round in 0..10 {
    ///         input.send(round);
    ///         input.advance_to(round + 1);
    ///         worker.step();
    ///     }
    /// });
    /// ```
    fn new_input<D: Data>(&mut self) -> (Handle<T, D>, Stream<Child<'a, Root<A>, T>, D>);

    /// Create a new stream from a supplied interactive handle.
    ///
    /// This method creates a new timely stream whose data are supplied interactively through the `handle`
    /// argument. Each handle may be used multiple times (or not at all), and will clone data as appropriate
    /// if it as attached to more than one stream.
    ///
    /// #Examples
    /// ```
    /// use timely::*;
    /// use timely::dataflow::operators::{Input, Inspect};
    /// use timely::dataflow::operators::input::Handle;
    ///
    /// // construct and execute a timely dataflow
    /// timely::execute(Configuration::Thread, |worker| {
    ///
    ///     // add an input and base computation off of it
    ///     let mut input = Handle::new();
    ///     worker.dataflow(|scope| {
    ///         scope.input_from(&mut input)
    ///              .inspect(|x| println!("hello {:?}", x));
    ///     });
    ///
    ///     // introduce input, advance computation
    ///     for round in 0..10 {
    ///         input.send(round);
    ///         input.advance_to(round + 1);
    ///         worker.step();
    ///     }
    /// });
    /// ```
    fn input_from<D: Data>(&mut self, handle: &mut Handle<T, D>) -> Stream<Child<'a, Root<A>, T>, D>;
}

impl<'a, A: Allocate, T: Timestamp+Ord> Input<'a, A, T> for Child<'a, Root<A>, T> {
    fn new_input<D: Data>(&mut self) -> (Handle<T, D>, Stream<Child<'a, Root<A>, T>, D>) {
        let mut handle = Handle::new();
        let stream = self.input_from(&mut handle);
        (handle, stream)
    }

    fn input_from<D: Data>(&mut self, handle: &mut Handle<T, D>) -> Stream<Child<'a, Root<A>, T>, D> {

        let (output, registrar) = Tee::<Product<RootTimestamp, T>, D>::new();
        let produced = Rc::new(RefCell::new(CountMap::new()));
        let counter = Counter::new(output, produced.clone());

        let progress = Rc::new(RefCell::new(CountMap::new()));

        handle.register(counter, progress.clone());

        let copies = self.peers();

        let index = self.add_operator(Operator {
            progress: progress.clone(),
            messages: produced.clone(),
            copies:   copies,
        });

        Stream::new(Source { index: index, port: 0 }, registrar, self.clone())
    }
}

struct Operator<T:Timestamp+Ord> {
    progress:   Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>,           // times closed since last asked
    messages:   Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>,           // messages sent since last asked
    copies:     usize,
}

impl<T:Timestamp+Ord> Operate<Product<RootTimestamp, T>> for Operator<T> {
    fn name(&self) -> String { "Input".to_owned() }
    fn inputs(&self) -> usize { 0 }
    fn outputs(&self) -> usize { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<<Product<RootTimestamp, T> as Timestamp>::Summary>>>,
                                           Vec<CountMap<Product<RootTimestamp, T>>>) {
        let mut map = CountMap::new();
        map.update(&Default::default(), self.copies as i64);
        (Vec::new(), vec![map])
    }

    fn pull_internal_progress(&mut self,_messages_consumed: &mut [CountMap<Product<RootTimestamp, T>>],
                                         frontier_progress: &mut [CountMap<Product<RootTimestamp, T>>],
                                         messages_produced: &mut [CountMap<Product<RootTimestamp, T>>]) -> bool
    {
        self.messages.borrow_mut().drain_into(&mut messages_produced[0]);
        self.progress.borrow_mut().drain_into(&mut frontier_progress[0]);
        false
    }

    fn notify_me(&self) -> bool { false }
}

/// A handle to an input `Stream`, used to introduce data to a timely dataflow computation.
pub struct Handle<T: Timestamp, D: Data> {
    progress: Vec<Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>>,
    pushers: Vec<Counter<Product<RootTimestamp, T>, D, Tee<Product<RootTimestamp, T>, D>>>,
    buffer1: Vec<D>,
    buffer2: Vec<D>,
    now_at: Product<RootTimestamp, T>,
}

impl<T:Timestamp, D: Data> Handle<T, D> {

    /// Allocates a new input handle, from which one can create timely streams.
    pub fn new() -> Self {
        Handle {
            progress: Vec::new(),
            pushers: Vec::new(),
            buffer1: Vec::with_capacity(Content::<D>::default_length()),
            buffer2: Vec::with_capacity(Content::<D>::default_length()),
            now_at: Default::default(),
        }
    }

    fn register(
        &mut self,
        pusher: Counter<Product<RootTimestamp, T>, D, Tee<Product<RootTimestamp, T>, D>>,
        progress: Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>
    ) {
        // flush current contents, so new registrant does not see existing data.
        if !self.buffer1.is_empty() { self.flush(); }

        // we need to produce an appropriate update to the capabilities for `progress`, in case a
        // user has decided to drive the handle around a bit before registering it.
        progress.borrow_mut().update(&Default::default(), -1);
        progress.borrow_mut().update(&self.now_at, 1);

        self.progress.push(progress);
        self.pushers.push(pusher);
    }

    // flushes our buffer at each of the destinations. there can be more than one; clone if needed.
    fn flush(&mut self) {
        for index in 0 .. self.pushers.len() {
            if index < self.pushers.len() - 1 {
                self.buffer2.extend_from_slice(&self.buffer1[..]);
                Content::push_at(&mut self.buffer2, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer2.is_empty());
            }
            else {
                Content::push_at(&mut self.buffer1, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer1.is_empty());
            }
        }
        self.buffer1.clear();
    }

    // closes the current epoch, flushing if needed, shutting if needed, and updating the frontier.
    fn close_epoch(&mut self) {
        if !self.buffer1.is_empty() { self.flush(); }
        for pusher in self.pushers.iter_mut() {
            pusher.done();
        }
        for progress in self.progress.iter() {
            progress.borrow_mut().update(&self.now_at, -1);
        }
    }

    #[inline(always)]
    /// Sends one record into the corresponding timely dataflow `Stream`, at the current epoch.
    pub fn send(&mut self, data: D) {
        // assert!(self.buffer.capacity() == Content::<D>::default_length());
        self.buffer1.push(data);
        if self.buffer1.len() == self.buffer1.capacity() {
            self.flush();
        }
    }

    /// Sends a batch of records into the corresponding timely dataflow `Stream`, at the current epoch.
    ///
    /// This method flushes single elements previously sent with `send`, to keep the insertion order.
    pub fn send_batch(&mut self, buffer: &mut Vec<D>) {

        // flush buffered elements to ensure local fifo.
        if !self.buffer1.is_empty() { self.flush(); }

        // push buffer (or clone of buffer) at each destination.
        for index in 0 .. self.pushers.len() {
            if index < self.pushers.len() - 1 {
                self.buffer2.extend_from_slice(&buffer[..]);
                Content::push_at(&mut self.buffer2, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer2.is_empty());
            }
            else {
                Content::push_at(buffer, self.now_at.clone(), &mut self.pushers[index]);
                assert!(buffer.is_empty());
            }
        }
        buffer.clear();
    }

    /// Advances the current epoch to `next`.
    ///
    /// This method allows timely dataflow to issue progress notifications as it can now determine
    /// that this input can no longer produce data at earlier timestamps.
    pub fn advance_to(&mut self, next: T) {
        assert!(self.now_at.inner.less_than(&next));
        self.close_epoch();
        self.now_at = RootTimestamp::new(next);
        for progress in self.progress.iter() {
            progress.borrow_mut().update(&self.now_at, 1);
        }
    }

    /// Closes the input.
    ///
    /// This method allows timely dataflow to issue all progress notifications blocked by this input
    /// and to begin to shut down operators, as this input can no longer produce data.
    pub fn close(self) { }

    /// Reports the current epoch.
    pub fn epoch(&self) -> &T {
        &self.now_at.inner
    }

    /// Reports the current timestamp.
    pub fn time(&self) -> &Product<RootTimestamp, T> {
        &self.now_at
    }
}

impl<T:Timestamp, D: Data> Drop for Handle<T, D> {
    fn drop(&mut self) {
        self.close_epoch();
    }
}
<commit_msg>advance_to to asserts less_equal, not less_than<commit_after>//! Create new `Streams` connected to external inputs.

use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;

use progress::frontier::Antichain;
use progress::{Operate, Timestamp};
use progress::nested::subgraph::Source;
use progress::count_map::CountMap;
use progress::timestamp::RootTimestamp;
use progress::nested::product::Product;

use timely_communication::Allocate;
use {Data, Push};
use dataflow::channels::Content;
use dataflow::channels::pushers::{Tee, Counter};

use dataflow::{Stream, Scope};
use dataflow::scopes::{Child, Root};

// TODO : This is an exogenous input, but it would be nice to wrap a Subgraph in something
// TODO : more like a harness, with direct access to its inputs.

// NOTE : This only takes a &self, not a &mut self, which works but is a bit weird.
// NOTE : Experiments with &mut indicate that the borrow of 'a lives for too long.
// NOTE : Might be able to fix with another lifetime parameter, say 'c: 'a.

/// Create a new `Stream` and `Handle` through which to supply input.
pub trait Input<'a, A: Allocate, T: Timestamp+Ord> {
    /// Create a new `Stream` and `Handle` through which to supply input.
    ///
    /// The `new_input` method returns a pair `(Handle, Stream)` where the `Stream` can be used
    /// immediately for timely dataflow construction, and the `Handle` is later used to introduce
    /// data into the timely dataflow computation.
    ///
    /// The `Handle` also provides a means to indicate
    /// to timely dataflow that the input has advanced beyond certain timestamps, allowing timely
    /// to issue progress notifications.
    ///
    /// #Examples
    /// ```
    /// use timely::*;
    /// use timely::dataflow::operators::{Input, Inspect};
    ///
    /// // construct and execute a timely dataflow
    /// timely::execute(Configuration::Thread, |worker| {
    ///
    ///     // add an input and base computation off of it
    ///     let mut input = worker.dataflow(|scope| {
    ///         let (input, stream) = scope.new_input();
    ///         stream.inspect(|x| println!("hello {:?}", x));
    ///         input
    ///     });
    ///
    ///     // introduce input, advance computation
    ///     for round in 0..10 {
    ///         input.send(round);
    ///         input.advance_to(round + 1);
    ///         worker.step();
    ///     }
    /// });
    /// ```
    fn new_input<D: Data>(&mut self) -> (Handle<T, D>, Stream<Child<'a, Root<A>, T>, D>);

    /// Create a new stream from a supplied interactive handle.
    ///
    /// This method creates a new timely stream whose data are supplied interactively through the `handle`
    /// argument. Each handle may be used multiple times (or not at all), and will clone data as appropriate
    /// if it as attached to more than one stream.
    ///
    /// #Examples
    /// ```
    /// use timely::*;
    /// use timely::dataflow::operators::{Input, Inspect};
    /// use timely::dataflow::operators::input::Handle;
    ///
    /// // construct and execute a timely dataflow
    /// timely::execute(Configuration::Thread, |worker| {
    ///
    ///     // add an input and base computation off of it
    ///     let mut input = Handle::new();
    ///     worker.dataflow(|scope| {
    ///         scope.input_from(&mut input)
    ///              .inspect(|x| println!("hello {:?}", x));
    ///     });
    ///
    ///     // introduce input, advance computation
    ///     for round in 0..10 {
    ///         input.send(round);
    ///         input.advance_to(round + 1);
    ///         worker.step();
    ///     }
    /// });
    /// ```
    fn input_from<D: Data>(&mut self, handle: &mut Handle<T, D>) -> Stream<Child<'a, Root<A>, T>, D>;
}

impl<'a, A: Allocate, T: Timestamp+Ord> Input<'a, A, T> for Child<'a, Root<A>, T> {
    fn new_input<D: Data>(&mut self) -> (Handle<T, D>, Stream<Child<'a, Root<A>, T>, D>) {
        let mut handle = Handle::new();
        let stream = self.input_from(&mut handle);
        (handle, stream)
    }

    fn input_from<D: Data>(&mut self, handle: &mut Handle<T, D>) -> Stream<Child<'a, Root<A>, T>, D> {

        let (output, registrar) = Tee::<Product<RootTimestamp, T>, D>::new();
        let produced = Rc::new(RefCell::new(CountMap::new()));
        let counter = Counter::new(output, produced.clone());

        let progress = Rc::new(RefCell::new(CountMap::new()));

        handle.register(counter, progress.clone());

        let copies = self.peers();

        let index = self.add_operator(Operator {
            progress: progress.clone(),
            messages: produced.clone(),
            copies:   copies,
        });

        Stream::new(Source { index: index, port: 0 }, registrar, self.clone())
    }
}

struct Operator<T:Timestamp+Ord> {
    progress:   Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>,           // times closed since last asked
    messages:   Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>,           // messages sent since last asked
    copies:     usize,
}

impl<T:Timestamp+Ord> Operate<Product<RootTimestamp, T>> for Operator<T> {
    fn name(&self) -> String { "Input".to_owned() }
    fn inputs(&self) -> usize { 0 }
    fn outputs(&self) -> usize { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<<Product<RootTimestamp, T> as Timestamp>::Summary>>>,
                                           Vec<CountMap<Product<RootTimestamp, T>>>) {
        let mut map = CountMap::new();
        map.update(&Default::default(), self.copies as i64);
        (Vec::new(), vec![map])
    }

    fn pull_internal_progress(&mut self,_messages_consumed: &mut [CountMap<Product<RootTimestamp, T>>],
                                         frontier_progress: &mut [CountMap<Product<RootTimestamp, T>>],
                                         messages_produced: &mut [CountMap<Product<RootTimestamp, T>>]) -> bool
    {
        self.messages.borrow_mut().drain_into(&mut messages_produced[0]);
        self.progress.borrow_mut().drain_into(&mut frontier_progress[0]);
        false
    }

    fn notify_me(&self) -> bool { false }
}

/// A handle to an input `Stream`, used to introduce data to a timely dataflow computation.
pub struct Handle<T: Timestamp, D: Data> {
    progress: Vec<Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>>,
    pushers: Vec<Counter<Product<RootTimestamp, T>, D, Tee<Product<RootTimestamp, T>, D>>>,
    buffer1: Vec<D>,
    buffer2: Vec<D>,
    now_at: Product<RootTimestamp, T>,
}

impl<T:Timestamp, D: Data> Handle<T, D> {

    /// Allocates a new input handle, from which one can create timely streams.
    pub fn new() -> Self {
        Handle {
            progress: Vec::new(),
            pushers: Vec::new(),
            buffer1: Vec::with_capacity(Content::<D>::default_length()),
            buffer2: Vec::with_capacity(Content::<D>::default_length()),
            now_at: Default::default(),
        }
    }

    fn register(
        &mut self,
        pusher: Counter<Product<RootTimestamp, T>, D, Tee<Product<RootTimestamp, T>, D>>,
        progress: Rc<RefCell<CountMap<Product<RootTimestamp, T>>>>
    ) {
        // flush current contents, so new registrant does not see existing data.
        if !self.buffer1.is_empty() { self.flush(); }

        // we need to produce an appropriate update to the capabilities for `progress`, in case a
        // user has decided to drive the handle around a bit before registering it.
        progress.borrow_mut().update(&Default::default(), -1);
        progress.borrow_mut().update(&self.now_at, 1);

        self.progress.push(progress);
        self.pushers.push(pusher);
    }

    // flushes our buffer at each of the destinations. there can be more than one; clone if needed.
    fn flush(&mut self) {
        for index in 0 .. self.pushers.len() {
            if index < self.pushers.len() - 1 {
                self.buffer2.extend_from_slice(&self.buffer1[..]);
                Content::push_at(&mut self.buffer2, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer2.is_empty());
            }
            else {
                Content::push_at(&mut self.buffer1, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer1.is_empty());
            }
        }
        self.buffer1.clear();
    }

    // closes the current epoch, flushing if needed, shutting if needed, and updating the frontier.
    fn close_epoch(&mut self) {
        if !self.buffer1.is_empty() { self.flush(); }
        for pusher in self.pushers.iter_mut() {
            pusher.done();
        }
        for progress in self.progress.iter() {
            progress.borrow_mut().update(&self.now_at, -1);
        }
    }

    #[inline(always)]
    /// Sends one record into the corresponding timely dataflow `Stream`, at the current epoch.
    pub fn send(&mut self, data: D) {
        // assert!(self.buffer.capacity() == Content::<D>::default_length());
        self.buffer1.push(data);
        if self.buffer1.len() == self.buffer1.capacity() {
            self.flush();
        }
    }

    /// Sends a batch of records into the corresponding timely dataflow `Stream`, at the current epoch.
    ///
    /// This method flushes single elements previously sent with `send`, to keep the insertion order.
    pub fn send_batch(&mut self, buffer: &mut Vec<D>) {

        // flush buffered elements to ensure local fifo.
        if !self.buffer1.is_empty() { self.flush(); }

        // push buffer (or clone of buffer) at each destination.
        for index in 0 .. self.pushers.len() {
            if index < self.pushers.len() - 1 {
                self.buffer2.extend_from_slice(&buffer[..]);
                Content::push_at(&mut self.buffer2, self.now_at.clone(), &mut self.pushers[index]);
                assert!(self.buffer2.is_empty());
            }
            else {
                Content::push_at(buffer, self.now_at.clone(), &mut self.pushers[index]);
                assert!(buffer.is_empty());
            }
        }
        buffer.clear();
    }

    /// Advances the current epoch to `next`.
    ///
    /// This method allows timely dataflow to issue progress notifications as it can now determine
    /// that this input can no longer produce data at earlier timestamps.
    pub fn advance_to(&mut self, next: T) {
        assert!(self.now_at.inner.less_equal(&next));
        self.close_epoch();
        self.now_at = RootTimestamp::new(next);
        for progress in self.progress.iter() {
            progress.borrow_mut().update(&self.now_at, 1);
        }
    }

    /// Closes the input.
    ///
    /// This method allows timely dataflow to issue all progress notifications blocked by this input
    /// and to begin to shut down operators, as this input can no longer produce data.
    pub fn close(self) { }

    /// Reports the current epoch.
    pub fn epoch(&self) -> &T {
        &self.now_at.inner
    }

    /// Reports the current timestamp.
    pub fn time(&self) -> &Product<RootTimestamp, T> {
        &self.now_at
    }
}

impl<T:Timestamp, D: Data> Drop for Handle<T, D> {
    fn drop(&mut self) {
        self.close_epoch();
    }
}
<|endoftext|>


<commit_before>extern crate cheddar;

fn main() {
    cheddar::Cheddar::new().expect("could not read manifest")
        .insert_code("#include <urweb.h>").run_build("ffi.h"); }
<commit_msg>New cheddar version<commit_after>extern crate cheddar;

fn main() {
    cheddar::Builder::c99().expect("could not read cargo manifest")
        .name("ffi.h")
        .insert_code("#include <urweb.h>")
        .output_directory(".")
        .run_build(); }
<|endoftext|>


<commit_before>use std::rt::io::mem::{MemReader, MemWriter};
use std::str;
use headers::{HeaderConvertible, HeaderValueByteIterator};

pub fn from_stream_with_str<T: HeaderConvertible>(s: &str) -> Option<T> {
    let bytes = s.as_bytes();
    let mut reader = MemReader::new(bytes.into_owned());
    reader.buf.push_all(bytes!("\r\n/"));
    let mut iter = HeaderValueByteIterator::new(&mut reader);
    HeaderConvertible::from_stream(&mut iter)
}

pub fn to_stream_into_str<T: HeaderConvertible>(v: &T) -> ~str {
    let mut writer = MemWriter::new();
    v.to_stream(&mut writer);
    str::from_utf8(writer.buf)
}

// Verify that a value cannot be successfully interpreted as a header value of the specified type.
#[inline]
pub fn assert_invalid<T: HeaderConvertible>(string: &str) {
    assert_eq!(from_stream_with_str::<T>(string), None);
}

// Verify that all of the methods from the HeaderConvertible trait work correctly for the given
// valid header value and correct decoded value.
#[inline]
pub fn assert_conversion_correct<T: HeaderConvertible>(string: &'static str, value: T) {
    assert_eq!(from_stream_with_str(string), Some(value.clone()));
    let s = to_stream_into_str(&value);
    assert_eq!(s.as_slice(), string);
    let s = value.http_value();
    assert_eq!(s.as_slice(), string);
}

// Verify that from_stream interprets the given valid header value correctly.
#[inline]
pub fn assert_interpretation_correct<T: HeaderConvertible>(string: &'static str, value: T) {
    assert_eq!(from_stream_with_str(string), Some(value));
}
<commit_msg>Don't use Mem{Reader,Writer}.buf<commit_after>use std::rt::io::mem::{MemReader, with_mem_writer};
use std::str;
use headers::{HeaderConvertible, HeaderValueByteIterator};

pub fn from_stream_with_str<T: HeaderConvertible>(s: &str) -> Option<T> {
    let mut bytes = s.as_bytes().into_owned();
    bytes.push_all(bytes!("\r\n/"));

    let mut reader = MemReader::new(bytes.into_owned());
    let mut iter = HeaderValueByteIterator::new(&mut reader);
    HeaderConvertible::from_stream(&mut iter)
}

pub fn to_stream_into_str<T: HeaderConvertible>(v: &T) -> ~str {
    let contents = do with_mem_writer |writer|
      { v.to_stream(writer); };
    str::from_utf8(contents)
}

// Verify that a value cannot be successfully interpreted as a header value of the specified type.
#[inline]
pub fn assert_invalid<T: HeaderConvertible>(string: &str) {
    assert_eq!(from_stream_with_str::<T>(string), None);
}

// Verify that all of the methods from the HeaderConvertible trait work correctly for the given
// valid header value and correct decoded value.
#[inline]
pub fn assert_conversion_correct<T: HeaderConvertible>(string: &'static str, value: T) {
    assert_eq!(from_stream_with_str(string), Some(value.clone()));
    let s = to_stream_into_str(&value);
    assert_eq!(s.as_slice(), string);
    let s = value.http_value();
    assert_eq!(s.as_slice(), string);
}

// Verify that from_stream interprets the given valid header value correctly.
#[inline]
pub fn assert_interpretation_correct<T: HeaderConvertible>(string: &'static str, value: T) {
    assert_eq!(from_stream_with_str(string), Some(value));
}
<|endoftext|>


<commit_before>// Copyright 2012-2016 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::mem;

/// `BitSlice` provides helper methods for treating a `[usize]`
/// as a bitvector.
pub trait BitSlice {
    fn clear_bit(&mut self, idx: usize) -> bool;
    fn set_bit(&mut self, idx: usize) -> bool;
    fn get_bit(&self, idx: usize) -> bool;
}

impl BitSlice for [usize] {
    /// Clears bit at `idx` to 0; returns true iff this changed `self.`
    fn clear_bit(&mut self, idx: usize) -> bool {
        let words = self;
        debug!("clear_bit: words={} idx={}",
               bits_to_string(words, words.len() * mem::size_of::<usize>()), bit_str(idx));
        let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
        debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
        let oldv = words[word];
        let newv = oldv & !bit_mask;
        words[word] = newv;
        oldv != newv
    }

    /// Sets bit at `idx` to 1; returns true iff this changed `self.`
    fn set_bit(&mut self, idx: usize) -> bool {
        let words = self;
        debug!("set_bit: words={} idx={}",
               bits_to_string(words, words.len() * mem::size_of::<usize>()), bit_str(idx));
        let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
        debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
        let oldv = words[word];
        let newv = oldv | bit_mask;
        words[word] = newv;
        oldv != newv
    }

    /// Extracts value of bit at `idx` in `self`.
    fn get_bit(&self, idx: usize) -> bool {
        let words = self;
        let BitLookup { word, bit_mask, .. } = bit_lookup(idx);
        (words[word] & bit_mask) != 0
    }
}

struct BitLookup {
    /// An index of the word holding the bit in original `[usize]` of query.
    word: usize,
    /// Index of the particular bit within the word holding the bit.
    bit_in_word: usize,
    /// Word with single 1-bit set corresponding to where the bit is located.
    bit_mask: usize,
}

#[inline]
fn bit_lookup(bit: usize) -> BitLookup {
    let usize_bits = mem::size_of::<usize>() * 8;
    let word = bit / usize_bits;
    let bit_in_word = bit % usize_bits;
    let bit_mask = 1 << bit_in_word;
    BitLookup { word: word, bit_in_word: bit_in_word, bit_mask: bit_mask }
}

fn bit_str(bit: usize) -> String {
    let byte = bit >> 3;
    let lobits = 1 << (bit & 0b111);
    format!("[{}:{}-{:02x}]", bit, byte, lobits)
}

pub fn bits_to_string(words: &[usize], bytes: usize) -> String {
    let mut result = String::new();
    let mut sep = '[';

    // Note: this is a little endian printout of bytes.

    let mut i = 0;
    for &word in words.iter() {
        let mut v = word;
        for _ in 0..mem::size_of::<usize>() {
            let byte = v & 0xFF;
            if i >= bytes {
                assert!(byte == 0);
            } else {
                result.push(sep);
                result.push_str(&format!("{:02x}", byte));
            }
            v >>= 8;
            i += 1;
            sep = '-';
        }
    }
    result.push(']');
    return result
}
<commit_msg>fixes to `librustc_borrowck::bitslice::bits_to_string`, used for graphviz printing.<commit_after>// Copyright 2012-2016 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::mem;

/// `BitSlice` provides helper methods for treating a `[usize]`
/// as a bitvector.
pub trait BitSlice {
    fn clear_bit(&mut self, idx: usize) -> bool;
    fn set_bit(&mut self, idx: usize) -> bool;
    fn get_bit(&self, idx: usize) -> bool;
}

impl BitSlice for [usize] {
    /// Clears bit at `idx` to 0; returns true iff this changed `self.`
    fn clear_bit(&mut self, idx: usize) -> bool {
        let words = self;
        debug!("clear_bit: words={} idx={}",
               bits_to_string(words, words.len() * mem::size_of::<usize>()), bit_str(idx));
        let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
        debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
        let oldv = words[word];
        let newv = oldv & !bit_mask;
        words[word] = newv;
        oldv != newv
    }

    /// Sets bit at `idx` to 1; returns true iff this changed `self.`
    fn set_bit(&mut self, idx: usize) -> bool {
        let words = self;
        debug!("set_bit: words={} idx={}",
               bits_to_string(words, words.len() * mem::size_of::<usize>()), bit_str(idx));
        let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
        debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
        let oldv = words[word];
        let newv = oldv | bit_mask;
        words[word] = newv;
        oldv != newv
    }

    /// Extracts value of bit at `idx` in `self`.
    fn get_bit(&self, idx: usize) -> bool {
        let words = self;
        let BitLookup { word, bit_mask, .. } = bit_lookup(idx);
        (words[word] & bit_mask) != 0
    }
}

struct BitLookup {
    /// An index of the word holding the bit in original `[usize]` of query.
    word: usize,
    /// Index of the particular bit within the word holding the bit.
    bit_in_word: usize,
    /// Word with single 1-bit set corresponding to where the bit is located.
    bit_mask: usize,
}

#[inline]
fn bit_lookup(bit: usize) -> BitLookup {
    let usize_bits = mem::size_of::<usize>() * 8;
    let word = bit / usize_bits;
    let bit_in_word = bit % usize_bits;
    let bit_mask = 1 << bit_in_word;
    BitLookup { word: word, bit_in_word: bit_in_word, bit_mask: bit_mask }
}

fn bit_str(bit: usize) -> String {
    let byte = bit >> 3;
    let lobits = 1 << (bit & 0b111);
    format!("[{}:{}-{:02x}]", bit, byte, lobits)
}

pub fn bits_to_string(words: &[usize], bits: usize) -> String {
    let mut result = String::new();
    let mut sep = '[';

    // Note: this is a little endian printout of bytes.

    // i tracks how many bits we have printed so far.
    let mut i = 0;
    for &word in words.iter() {
        let mut v = word;
        loop { // for each byte in `v`:
            let remain = bits - i;
            // If less than a byte remains, then mask just that many bits.
            let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
            assert!(mask <= 0xFF);
            let byte = v & mask;

            result.push(sep);
            result.push_str(&format!("{:02x}", byte));

            if remain <= 8 { break; }
            v >>= 8;
            i += 8;
            sep = '-';
        }
    }
    result.push(']');
    return result
}
<|endoftext|>


<commit_before>extern crate sendmail;
use sendmail::email;

fn main() {

    // Configure email body and header
    email::send_new(
        // From Address
        "test@localhost",
        // To Address
        &["root@localhost"],
        // Subject
        "Subject - Hello World!",
        // Body
        "
I am the body. Hello Wolrd!

And I accept html.
"
    ).unwrap();
}
<commit_msg>chnage to just send<commit_after>extern crate sendmail;
use sendmail::email;

fn main() {

    // Configure email body and header
    email::send(
        // From Address
        "test@localhost",
        // To Address
        &["root@localhost"],
        // Subject
        "Subject - Hello World!",
        // Body
        "
I am the body. Hello Wolrd!

And I accept html.
"
    ).unwrap();
}
<|endoftext|>