<commit_before>use database::schema::*;
use database::models::U64;

insertable! {
  #[derive(Debug, Queryable, Identifiable, AsChangeset)]
  #[table_name = "tag_queue"]
  pub struct TagQueue,
  #[derive(Debug, Insertable)]
  #[table_name = "tag_queue"]
  pub struct NewTagQueue {
    pub user_id: U64,
    pub server_id: U64,
    pub server: String,
    pub character: String
  }
}

impl NewTagQueue {
  pub fn new(user_id: u64, server_id: u64, server: &str, character: &str) -> Self {
    NewTagQueue {
      user_id: user_id.into(),
      server_id: server_id.into(),
      server: server.to_owned(),
      character: character.to_owned()
    }
  }
}
<commit_msg>fix: correct order of tag queue model<commit_after>use database::schema::*;
use database::models::U64;

insertable! {
  #[derive(Debug, Queryable, Identifiable, AsChangeset)]
  #[table_name = "tag_queue"]
  pub struct TagQueue,
  #[derive(Debug, Insertable)]
  #[table_name = "tag_queue"]
  pub struct NewTagQueue {
    pub server_id: U64,
    pub user_id: U64,
    pub server: String,
    pub character: String
  }
}

impl NewTagQueue {
  pub fn new(user_id: u64, server_id: u64, server: &str, character: &str) -> Self {
    NewTagQueue {
      user_id: user_id.into(),
      server_id: server_id.into(),
      server: server.to_owned(),
      character: character.to_owned()
    }
  }
}
<|endoftext|>


<commit_before>//! A LinkedList that lets you insert elements from the front or the end of the list.
//! TODO: Add the ability to insert in-between a Node.
//! Lots of thanks to reem and Sharp for help with this from the #rust channel

use std::mem;

/// A Node is the basic unit in a LinkedList which stores the payload of type T.
#[derive(Debug,PartialEq)]
struct Node<T> {
    /// The payload of type T that is wrapped aorund a Node.
    pub payload: T,
    /// An Option of a boxed Node<T> that would point to the next Node<T>.
    next: Option<Box<Node<T>>>,
    /// An Option of a boxed Node<T> that would point to the previous Node<T>.
    prev: Option<Box<Node<T>>>,
}

impl<T> Node<T> {

    pub fn new(payload: T) -> Node<T> {
        //! Creates a instance of a `Node` with `next` and `prev` point to a Option::Node.
        Node::<T> {
            payload: payload,
            next: None,
            prev: None,
        }
    }

    pub fn payload(&self) -> Option<&T> {
        //! Access to a payload of Node.
        Some(&self.payload)
    }

    pub fn insert_after(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        //! Takes a new boxed Node<T> and swaps it with any existing Node after the current one.
        //! We replace any Option::None or Option::Some with a new Option<Box<Node<T>>>
        mem::swap(&mut new.next, &mut self.next);
        mem::replace(&mut self.next, Some(new))
    }

    pub fn insert_before(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        //! Takes a new boxed Node<T> and swaps it with any existing Node after the current one.
        //! We replace any Option::None or Option::Some with a new Option<Box<Node<T>>>
        mem::swap(&mut new.prev, &mut self.prev);
        mem::replace(&mut self.prev, Some(new))
    }

    /*pub fn remove_after(&mut self) -> Option<Box<Node<T>>> {
        //! Removes the Node after the current node.
        match self.next.take() {
            Some(mut next)  => {
                mem::swap(&mut self.next, &mut next.next);
                Some(next)
            },
            None => None,
        }
    }*/

    pub fn remove_before(&mut self) -> Option<Box<Node<T>>> {
        //! Removes the Node before the current node.
        match self.prev.take() {
            Some(mut prev)  => {
                mem::swap(&mut self.prev, &mut prev.prev);
                Some(prev)
            },
            None => None,
        }
    }

    pub fn next(&mut self) -> Option<&mut T> {
        //! Goes to the next Node and returns an Option to it.
        let Node {
            ref mut payload,
            ref mut prev,
            ref mut next,
        } = *self;

        match *next {
            Some(ref mut next) => {
                mem::swap(&mut next.payload, payload);

                let mut next = &mut **next;     // Cannot completely understand this bit yet.
                mem::swap(&mut next.next, &mut next.prev);

                mem::swap(&mut next.prev, prev);
            },
            None    => return None,
        }
        mem::swap(prev, next);
        Some(payload)
    }
}

/// A LinkedList is the struct that you would need to use to create a list of elements.
/// It contains a pointer to the first and last node in the list represented as `head and `tail`
/// respectively.
pub struct LinkedList<T> {
    /// First element in the list.
    head: Option<Box<Node<T>>>,
    /// Last element in the list.
    tail: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        //! Create a new LinkedList to contain a payloads with type T.
        LinkedList::<T> {
            head: None,
            tail: None,
        }
    }
}

#[test]
fn node_new() {
    let expected = Node {
        payload: "test",
        next: None,
        prev: None,
    };

    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.prev,     node.prev);
}

#[test]
fn node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}

#[test]
fn node_insert_after() {
    let mut node: Node<&str> = Node::new("one");
    node.insert_after(Box::new(Node::new("two")));
    assert_eq!("two", node.next.unwrap().payload);

}

#[test]
fn node_insert_before() {
    let mut node: Node<&str> = Node::new("two");
    node.insert_before(Box::new(Node::new("one")));
    assert_eq!("one", node.prev.unwrap().payload);
}

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

}
<commit_msg>Added prev function and uncommented remove_after<commit_after>//! A LinkedList that lets you insert elements from the front or the end of the list.
//! TODO: Add the ability to insert in-between a Node.
//! Lots of thanks to reem and Sharp for help with this from the #rust channel

use std::mem;

/// A Node is the basic unit in a LinkedList which stores the payload of type T.
#[derive(Debug,PartialEq)]
struct Node<T> {
    /// The payload of type T that is wrapped aorund a Node.
    pub payload: T,
    /// An Option of a boxed Node<T> that would point to the next Node<T>.
    next: Option<Box<Node<T>>>,
    /// An Option of a boxed Node<T> that would point to the previous Node<T>.
    prev: Option<Box<Node<T>>>,
}

impl<T> Node<T> {

    pub fn new(payload: T) -> Node<T> {
        //! Creates a instance of a `Node` with `next` and `prev` point to a Option::Node.
        Node::<T> {
            payload: payload,
            next: None,
            prev: None,
        }
    }

    pub fn payload(&self) -> Option<&T> {
        //! Access to a payload of Node.
        Some(&self.payload)
    }

    pub fn insert_after(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        //! Takes a new boxed Node<T> and swaps it with any existing Node after the current one.
        //! We replace any Option::None or Option::Some with a new Option<Box<Node<T>>>
        mem::swap(&mut new.next, &mut self.next);
        mem::replace(&mut self.next, Some(new))
    }

    pub fn insert_before(&mut self, mut new: Box<Node<T>>) -> Option<Box<Node<T>>> {
        //! Takes a new boxed Node<T> and swaps it with any existing Node after the current one.
        //! We replace any Option::None or Option::Some with a new Option<Box<Node<T>>>
        mem::swap(&mut new.prev, &mut self.prev);
        mem::replace(&mut self.prev, Some(new))
    }

    pub fn remove_after(&mut self) -> Option<Box<Node<T>>> {
        //! Removes the Node after the current node.
        match self.next.take() {
            Some(mut next)  => {
                mem::swap(&mut self.next, &mut next.next);
                Some(next)
            },
            None => None,
        }
    }

    pub fn remove_before(&mut self) -> Option<Box<Node<T>>> {
        //! Removes the Node before the current node.
        match self.prev.take() {
            Some(mut prev)  => {
                mem::swap(&mut self.prev, &mut prev.prev);
                Some(prev)
            },
            None => None,
        }
    }

    pub fn next(&mut self) -> Option<&mut T> {
        //! Goes to the next Node and returns an Option to it.
        let Node {
            ref mut payload,
            ref mut prev,
            ref mut next,
        } = *self;

        match *next {
            Some(ref mut next) => {
                mem::swap(&mut next.payload, payload);

                let mut next = &mut **next;     // Cannot completely understand this bit yet.
                mem::swap(&mut next.next, &mut next.prev);

                mem::swap(&mut next.prev, prev);
            },
            None => return None,
        }
        mem::swap(prev, next);
        Some(payload)
    }

    pub fn prev(&mut self) -> Option<&mut T> {
        let Node {
            ref mut payload,
            ref mut prev,
            ref mut next,
        } = *self;

        match *prev {
            Some(ref mut prev) => {
                mem::swap(&mut prev.payload, payload);

                let mut prev = &mut **prev;     // Still don't understand this bit.
                mem::swap(&mut prev.prev, &mut prev.next);

                mem::swap(&mut prev.next, next);
            },
            None => return None,
        }
        mem::swap(prev, next);
        Some(payload)
    }
}

/// A LinkedList is the struct that you would need to use to create a list of elements.
/// It contains a pointer to the first and last node in the list represented as `head and `tail`
/// respectively.
pub struct LinkedList<T> {
    /// First element in the list.
    head: Option<Box<Node<T>>>,
    /// Last element in the list.
    tail: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        //! Create a new LinkedList to contain a payloads with type T.
        LinkedList::<T> {
            head: None,
            tail: None,
        }
    }
}

#[test]
fn node_new() {
    let expected = Node {
        payload: "test",
        next: None,
        prev: None,
    };

    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.prev,     node.prev);
}

#[test]
fn node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}

#[test]
fn node_insert_after() {
    let mut node: Node<&str> = Node::new("one");
    node.insert_after(Box::new(Node::new("two")));
    assert_eq!("two", node.next.unwrap().payload);

}

#[test]
fn node_insert_before() {
    let mut node: Node<&str> = Node::new("two");
    node.insert_before(Box::new(Node::new("one")));
    assert_eq!("one", node.prev.unwrap().payload);
}

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

}
<|endoftext|>


<commit_before>use bot::LalafellBot;
use listeners::ReceivesEvents;
use commands::*;
use discord::model::{Event, Message, ReactionEmoji};

use std::sync::Arc;
use std::collections::HashMap;

pub struct CommandListener<'a> {
  bot: Arc<LalafellBot>,
  commands: HashMap<Vec<String>, Box<Command<'a> + Send + Sync>>
}

impl<'a> CommandListener<'a> {
  pub fn new(bot: Arc<LalafellBot>) -> CommandListener<'a> {
    CommandListener {
      bot: bot,
      commands: Default::default()
    }
  }

  pub fn add_command<T: AsRef<str>>(&mut self, names: &[T], command: Box<Command<'a> + Send + Sync>) {
    self.commands.insert(names.iter().map(|t| t.as_ref().to_string()).collect(), command);
  }

  fn check_command(&self, message: &Message) {
    let parts: Vec<&str> = message.content.split_whitespace().collect();
    if parts.is_empty() {
      return;
    }
    let first = parts[0];
    if !first.starts_with('!') {
      return;
    }
    let command_name = &first[1..].to_lowercase();
    let params = &parts[1..];
    let (_, command) = match self.commands.iter().find(|&(names, _)| names.contains(&command_name.to_lowercase())) {
      Some(c) => c,
      None => return
    };
    debug!("running command: {}", command_name);
    let run_result = command.run(message, params);
    match run_result {
      Ok(info) => match info.message {
        Some(embed) => { self.bot.discord.send_embed(message.channel_id, "", |e| embed(e).color(0x196358)).ok(); },
        None => { self.bot.discord.add_reaction(message.channel_id, message.id, ReactionEmoji::Unicode("\u{2705}".to_string())).ok(); }
      },
      Err(CommandFailure::Internal(info)) => {
        self.bot.discord.send_embed(message.channel_id, "",
                                    |e| e.description("An internal error happened while processing this command.")).ok();
        for err in info.error.iter() {
          error!("error: {:#?}", err);
        }
      },
      Err(CommandFailure::External(info)) => match info.message {
        Some(embed) => { self.bot.discord.send_embed(message.channel_id, "", |e| embed(e).color(0x63191b)).ok(); },
        None => { self.bot.discord.add_reaction(message.channel_id, message.id, ReactionEmoji::Unicode("\u{274c}".to_string())).ok(); }
      }
    }
  }
}

impl<'a> ReceivesEvents for CommandListener<'a> {
  fn receive(&self, event: &Event) {
    let message = match *event {
      Event::MessageCreate(ref m) => m,
      _ => return
    };
    self.check_command(message);
  }
}
<commit_msg>fix: don't create two new lowercase strings<commit_after>use bot::LalafellBot;
use listeners::ReceivesEvents;
use commands::*;
use discord::model::{Event, Message, ReactionEmoji};

use std::sync::Arc;
use std::collections::HashMap;

pub struct CommandListener<'a> {
  bot: Arc<LalafellBot>,
  commands: HashMap<Vec<String>, Box<Command<'a> + Send + Sync>>
}

impl<'a> CommandListener<'a> {
  pub fn new(bot: Arc<LalafellBot>) -> CommandListener<'a> {
    CommandListener {
      bot: bot,
      commands: Default::default()
    }
  }

  pub fn add_command<T: AsRef<str>>(&mut self, names: &[T], command: Box<Command<'a> + Send + Sync>) {
    self.commands.insert(names.iter().map(|t| t.as_ref().to_string()).collect(), command);
  }

  fn check_command(&self, message: &Message) {
    let parts: Vec<&str> = message.content.split_whitespace().collect();
    if parts.is_empty() {
      return;
    }
    let first = parts[0];
    if !first.starts_with('!') {
      return;
    }
    let command_name = first[1..].to_lowercase();
    let params = &parts[1..];
    let (_, command) = match self.commands.iter().find(|&(names, _)| names.contains(&command_name)) {
      Some(c) => c,
      None => return
    };
    debug!("running command: {}", command_name);
    let run_result = command.run(message, params);
    match run_result {
      Ok(info) => match info.message {
        Some(embed) => { self.bot.discord.send_embed(message.channel_id, "", |e| embed(e).color(0x196358)).ok(); },
        None => { self.bot.discord.add_reaction(message.channel_id, message.id, ReactionEmoji::Unicode("\u{2705}".to_string())).ok(); }
      },
      Err(CommandFailure::Internal(info)) => {
        self.bot.discord.send_embed(message.channel_id, "",
                                    |e| e.description("An internal error happened while processing this command.")).ok();
        for err in info.error.iter() {
          error!("error: {:#?}", err);
        }
      },
      Err(CommandFailure::External(info)) => match info.message {
        Some(embed) => { self.bot.discord.send_embed(message.channel_id, "", |e| embed(e).color(0x63191b)).ok(); },
        None => { self.bot.discord.add_reaction(message.channel_id, message.id, ReactionEmoji::Unicode("\u{274c}".to_string())).ok(); }
      }
    }
  }
}

impl<'a> ReceivesEvents for CommandListener<'a> {
  fn receive(&self, event: &Event) {
    let message = match *event {
      Event::MessageCreate(ref m) => m,
      _ => return
    };
    self.check_command(message);
  }
}
<|endoftext|>


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

// Searching for information from the cstore

use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
use middle::ty;
use middle::typeck;

use std::vec;
use reader = extra::ebml::reader;
use syntax::ast;
use syntax::ast_map;
use syntax::diagnostic::expect;

pub struct StaticMethodInfo {
    ident: ast::Ident,
    def_id: ast::DefId,
    purity: ast::Purity,
    vis: ast::Visibility,
}

pub fn get_symbol(cstore: @cstore::CStore, def: ast::DefId) -> ~str {
    let cdata = cstore.get_crate_data(def.crate).data();
    return decoder::get_symbol(cdata, def.node);
}

pub fn get_type_param_count(cstore: @cstore::CStore, def: ast::DefId)
                         -> uint {
    let cdata = cstore.get_crate_data(def.crate).data();
    return decoder::get_type_param_count(cdata, def.node);
}

/// Iterates over all the language items in the given crate.
pub fn each_lang_item(cstore: @cstore::CStore,
                      cnum: ast::CrateNum,
                      f: |ast::NodeId, uint| -> bool)
                      -> bool {
    let crate_data = cstore.get_crate_data(cnum);
    decoder::each_lang_item(crate_data, f)
}

/// Iterates over each child of the given item.
pub fn each_child_of_item(cstore: @cstore::CStore,
                          def_id: ast::DefId,
                          callback: |decoder::DefLike,
                                     ast::Ident,
                                     ast::Visibility|) {
    let crate_data = cstore.get_crate_data(def_id.crate);
    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
        cstore.get_crate_data(cnum)
    };
    decoder::each_child_of_item(cstore.intr,
                                crate_data,
                                def_id.node,
                                get_crate_data,
                                callback)
}

/// Iterates over each top-level crate item.
pub fn each_top_level_item_of_crate(cstore: @cstore::CStore,
                                    cnum: ast::CrateNum,
                                    callback: |decoder::DefLike,
                                               ast::Ident,
                                               ast::Visibility|) {
    let crate_data = cstore.get_crate_data(cnum);
    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
        cstore.get_crate_data(cnum)
    };
    decoder::each_top_level_item_of_crate(cstore.intr,
                                          crate_data,
                                          get_crate_data,
                                          callback)
}

pub fn get_item_path(tcx: ty::ctxt, def: ast::DefId) -> ast_map::Path {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    let path = decoder::get_item_path(cdata, def.node);

    // FIXME #1920: This path is not always correct if the crate is not linked
    // into the root namespace.
    vec::append(~[ast_map::PathMod(tcx.sess.ident_of(
        cdata.name))], path)
}

pub enum found_ast {
    found(ast::InlinedItem),
    found_parent(ast::DefId, ast::InlinedItem),
    not_found,
}

// Finds the AST for this item in the crate metadata, if any.  If the item was
// not marked for inlining, then the AST will not be present and hence none
// will be returned.
pub fn maybe_get_item_ast(tcx: ty::ctxt, def: ast::DefId,
                          decode_inlined_item: decoder::decode_inlined_item)
                       -> found_ast {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::maybe_get_item_ast(cdata, tcx, def.node,
                                decode_inlined_item)
}

pub fn get_enum_variants(tcx: ty::ctxt, def: ast::DefId)
                      -> ~[@ty::VariantInfo] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx)
}

/// Returns information about the given implementation.
pub fn get_impl(tcx: ty::ctxt, impl_def_id: ast::DefId)
                -> ty::Impl {
    let cdata = tcx.cstore.get_crate_data(impl_def_id.crate);
    decoder::get_impl(tcx.cstore.intr, cdata, impl_def_id.node, tcx)
}

pub fn get_method(tcx: ty::ctxt, def: ast::DefId) -> ty::Method {
    let cdata = tcx.cstore.get_crate_data(def.crate);
    decoder::get_method(tcx.cstore.intr, cdata, def.node, tcx)
}

pub fn get_method_name_and_explicit_self(cstore: @cstore::CStore,
                                         def: ast::DefId)
                                     -> (ast::Ident, ast::ExplicitSelf_)
{
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_method_name_and_explicit_self(cstore.intr, cdata, def.node)
}

pub fn get_trait_method_def_ids(cstore: @cstore::CStore,
                                def: ast::DefId) -> ~[ast::DefId] {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_trait_method_def_ids(cdata, def.node)
}

pub fn get_item_variances(cstore: @cstore::CStore,
                          def: ast::DefId) -> ty::ItemVariances {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_item_variances(cdata, def.node)
}

pub fn get_provided_trait_methods(tcx: ty::ctxt,
                                  def: ast::DefId)
                               -> ~[@ty::Method] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
}

pub fn get_supertraits(tcx: ty::ctxt, def: ast::DefId) -> ~[@ty::TraitRef] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_supertraits(cdata, def.node, tcx)
}

pub fn get_type_name_if_impl(cstore: @cstore::CStore, def: ast::DefId)
                          -> Option<ast::Ident> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_type_name_if_impl(cdata, def.node)
}

pub fn get_static_methods_if_impl(cstore: @cstore::CStore,
                                  def: ast::DefId)
                               -> Option<~[StaticMethodInfo]> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_static_methods_if_impl(cstore.intr, cdata, def.node)
}

pub fn get_item_attrs(cstore: @cstore::CStore,
                      def_id: ast::DefId,
                      f: |~[@ast::MetaItem]|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_item_attrs(cdata, def_id.node, f)
}

pub fn get_struct_fields(cstore: @cstore::CStore,
                         def: ast::DefId)
                      -> ~[ty::field_ty] {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_struct_fields(cstore.intr, cdata, def.node)
}

pub fn get_type(tcx: ty::ctxt,
                def: ast::DefId)
             -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_type(cdata, def.node, tcx)
}

pub fn get_trait_def(tcx: ty::ctxt, def: ast::DefId) -> ty::TraitDef {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_trait_def(cdata, def.node, tcx)
}

pub fn get_field_type(tcx: ty::ctxt, class_id: ast::DefId,
                      def: ast::DefId) -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(class_id.crate);
    let all_items = reader::get_doc(reader::Doc(cdata.data()), tag_items);
    debug!("Looking up {:?}", class_id);
    let class_doc = expect(tcx.diag,
                           decoder::maybe_find_item(class_id.node, all_items),
                           || format!("get_field_type: class ID {:?} not found",
                                   class_id) );
    debug!("looking up {:?} : {:?}", def, class_doc);
    let the_field = expect(tcx.diag,
        decoder::maybe_find_item(def.node, class_doc),
        || format!("get_field_type: in class {:?}, field ID {:?} not found",
                 class_id, def) );
    debug!("got field data {:?}", the_field);
    let ty = decoder::item_type(def, the_field, tcx, cdata);
    ty::ty_param_bounds_and_ty {
        generics: ty::Generics {type_param_defs: @~[],
                                region_param_defs: @[]},
        ty: ty
    }
}

// Given a def_id for an impl, return the trait it implements,
// if there is one.
pub fn get_impl_trait(tcx: ty::ctxt,
                      def: ast::DefId) -> Option<@ty::TraitRef> {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_trait(cdata, def.node, tcx)
}

// Given a def_id for an impl, return information about its vtables
pub fn get_impl_vtables(tcx: ty::ctxt,
                        def: ast::DefId) -> typeck::impl_res {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_vtables(cdata, def.node, tcx)
}

pub fn get_impl_method(cstore: @cstore::CStore,
                       def: ast::DefId,
                       mname: ast::Ident)
                    -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_method(cstore.intr, cdata, def.node, mname)
}

pub fn get_item_visibility(cstore: @cstore::CStore,
                           def_id: ast::DefId)
                        -> ast::Visibility {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_item_visibility(cdata, def_id.node)
}

pub fn get_native_libraries(cstore: @cstore::CStore,
                            crate_num: ast::CrateNum)
                                -> ~[(cstore::NativeLibaryKind, ~str)] {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_native_libraries(cdata)
}

pub fn each_impl(cstore: @cstore::CStore,
                 crate_num: ast::CrateNum,
                 callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::each_impl(cdata, callback)
}

pub fn each_implementation_for_type(cstore: @cstore::CStore,
                                    def_id: ast::DefId,
                                    callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::each_implementation_for_type(cdata, def_id.node, callback)
}

pub fn each_implementation_for_trait(cstore: @cstore::CStore,
                                     def_id: ast::DefId,
                                     callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::each_implementation_for_trait(cdata, def_id.node, callback)
}

/// If the given def ID describes a method belonging to a trait (either a
/// default method or an implementation of a trait method), returns the ID of
/// the trait that the method belongs to. Otherwise, returns `None`.
pub fn get_trait_of_method(cstore: @cstore::CStore,
                           def_id: ast::DefId,
                           tcx: ty::ctxt)
                           -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_trait_of_method(cdata, def_id.node, tcx)
}

pub fn get_macro_registrar_fn(cstore: @cstore::CStore,
                              crate_num: ast::CrateNum)
                              -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_macro_registrar_fn(cdata)
}

pub fn get_exported_macros(cstore: @cstore::CStore,
                           crate_num: ast::CrateNum)
                           -> ~[@ast::Item] {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_exported_macros(cdata)
}
<commit_msg>rustc/metadata: Removed stray debug statements<commit_after>// Copyright 2012-2014 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.

// Searching for information from the cstore

use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
use middle::ty;
use middle::typeck;

use std::vec;
use reader = extra::ebml::reader;
use syntax::ast;
use syntax::ast_map;
use syntax::diagnostic::expect;

pub struct StaticMethodInfo {
    ident: ast::Ident,
    def_id: ast::DefId,
    purity: ast::Purity,
    vis: ast::Visibility,
}

pub fn get_symbol(cstore: @cstore::CStore, def: ast::DefId) -> ~str {
    let cdata = cstore.get_crate_data(def.crate).data();
    return decoder::get_symbol(cdata, def.node);
}

pub fn get_type_param_count(cstore: @cstore::CStore, def: ast::DefId)
                         -> uint {
    let cdata = cstore.get_crate_data(def.crate).data();
    return decoder::get_type_param_count(cdata, def.node);
}

/// Iterates over all the language items in the given crate.
pub fn each_lang_item(cstore: @cstore::CStore,
                      cnum: ast::CrateNum,
                      f: |ast::NodeId, uint| -> bool)
                      -> bool {
    let crate_data = cstore.get_crate_data(cnum);
    decoder::each_lang_item(crate_data, f)
}

/// Iterates over each child of the given item.
pub fn each_child_of_item(cstore: @cstore::CStore,
                          def_id: ast::DefId,
                          callback: |decoder::DefLike,
                                     ast::Ident,
                                     ast::Visibility|) {
    let crate_data = cstore.get_crate_data(def_id.crate);
    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
        cstore.get_crate_data(cnum)
    };
    decoder::each_child_of_item(cstore.intr,
                                crate_data,
                                def_id.node,
                                get_crate_data,
                                callback)
}

/// Iterates over each top-level crate item.
pub fn each_top_level_item_of_crate(cstore: @cstore::CStore,
                                    cnum: ast::CrateNum,
                                    callback: |decoder::DefLike,
                                               ast::Ident,
                                               ast::Visibility|) {
    let crate_data = cstore.get_crate_data(cnum);
    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
        cstore.get_crate_data(cnum)
    };
    decoder::each_top_level_item_of_crate(cstore.intr,
                                          crate_data,
                                          get_crate_data,
                                          callback)
}

pub fn get_item_path(tcx: ty::ctxt, def: ast::DefId) -> ast_map::Path {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    let path = decoder::get_item_path(cdata, def.node);

    // FIXME #1920: This path is not always correct if the crate is not linked
    // into the root namespace.
    vec::append(~[ast_map::PathMod(tcx.sess.ident_of(
        cdata.name))], path)
}

pub enum found_ast {
    found(ast::InlinedItem),
    found_parent(ast::DefId, ast::InlinedItem),
    not_found,
}

// Finds the AST for this item in the crate metadata, if any.  If the item was
// not marked for inlining, then the AST will not be present and hence none
// will be returned.
pub fn maybe_get_item_ast(tcx: ty::ctxt, def: ast::DefId,
                          decode_inlined_item: decoder::decode_inlined_item)
                       -> found_ast {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::maybe_get_item_ast(cdata, tcx, def.node,
                                decode_inlined_item)
}

pub fn get_enum_variants(tcx: ty::ctxt, def: ast::DefId)
                      -> ~[@ty::VariantInfo] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx)
}

/// Returns information about the given implementation.
pub fn get_impl(tcx: ty::ctxt, impl_def_id: ast::DefId)
                -> ty::Impl {
    let cdata = tcx.cstore.get_crate_data(impl_def_id.crate);
    decoder::get_impl(tcx.cstore.intr, cdata, impl_def_id.node, tcx)
}

pub fn get_method(tcx: ty::ctxt, def: ast::DefId) -> ty::Method {
    let cdata = tcx.cstore.get_crate_data(def.crate);
    decoder::get_method(tcx.cstore.intr, cdata, def.node, tcx)
}

pub fn get_method_name_and_explicit_self(cstore: @cstore::CStore,
                                         def: ast::DefId)
                                     -> (ast::Ident, ast::ExplicitSelf_)
{
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_method_name_and_explicit_self(cstore.intr, cdata, def.node)
}

pub fn get_trait_method_def_ids(cstore: @cstore::CStore,
                                def: ast::DefId) -> ~[ast::DefId] {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_trait_method_def_ids(cdata, def.node)
}

pub fn get_item_variances(cstore: @cstore::CStore,
                          def: ast::DefId) -> ty::ItemVariances {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_item_variances(cdata, def.node)
}

pub fn get_provided_trait_methods(tcx: ty::ctxt,
                                  def: ast::DefId)
                               -> ~[@ty::Method] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
}

pub fn get_supertraits(tcx: ty::ctxt, def: ast::DefId) -> ~[@ty::TraitRef] {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_supertraits(cdata, def.node, tcx)
}

pub fn get_type_name_if_impl(cstore: @cstore::CStore, def: ast::DefId)
                          -> Option<ast::Ident> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_type_name_if_impl(cdata, def.node)
}

pub fn get_static_methods_if_impl(cstore: @cstore::CStore,
                                  def: ast::DefId)
                               -> Option<~[StaticMethodInfo]> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_static_methods_if_impl(cstore.intr, cdata, def.node)
}

pub fn get_item_attrs(cstore: @cstore::CStore,
                      def_id: ast::DefId,
                      f: |~[@ast::MetaItem]|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_item_attrs(cdata, def_id.node, f)
}

pub fn get_struct_fields(cstore: @cstore::CStore,
                         def: ast::DefId)
                      -> ~[ty::field_ty] {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_struct_fields(cstore.intr, cdata, def.node)
}

pub fn get_type(tcx: ty::ctxt,
                def: ast::DefId)
             -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_type(cdata, def.node, tcx)
}

pub fn get_trait_def(tcx: ty::ctxt, def: ast::DefId) -> ty::TraitDef {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_trait_def(cdata, def.node, tcx)
}

pub fn get_field_type(tcx: ty::ctxt, class_id: ast::DefId,
                      def: ast::DefId) -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(class_id.crate);
    let all_items = reader::get_doc(reader::Doc(cdata.data()), tag_items);
    let class_doc = expect(tcx.diag,
                           decoder::maybe_find_item(class_id.node, all_items),
                           || format!("get_field_type: class ID {:?} not found",
                                   class_id) );
    let the_field = expect(tcx.diag,
        decoder::maybe_find_item(def.node, class_doc),
        || format!("get_field_type: in class {:?}, field ID {:?} not found",
                 class_id, def) );
    let ty = decoder::item_type(def, the_field, tcx, cdata);
    ty::ty_param_bounds_and_ty {
        generics: ty::Generics {type_param_defs: @~[],
                                region_param_defs: @[]},
        ty: ty
    }
}

// Given a def_id for an impl, return the trait it implements,
// if there is one.
pub fn get_impl_trait(tcx: ty::ctxt,
                      def: ast::DefId) -> Option<@ty::TraitRef> {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_trait(cdata, def.node, tcx)
}

// Given a def_id for an impl, return information about its vtables
pub fn get_impl_vtables(tcx: ty::ctxt,
                        def: ast::DefId) -> typeck::impl_res {
    let cstore = tcx.cstore;
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_vtables(cdata, def.node, tcx)
}

pub fn get_impl_method(cstore: @cstore::CStore,
                       def: ast::DefId,
                       mname: ast::Ident)
                    -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(def.crate);
    decoder::get_impl_method(cstore.intr, cdata, def.node, mname)
}

pub fn get_item_visibility(cstore: @cstore::CStore,
                           def_id: ast::DefId)
                        -> ast::Visibility {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_item_visibility(cdata, def_id.node)
}

pub fn get_native_libraries(cstore: @cstore::CStore,
                            crate_num: ast::CrateNum)
                                -> ~[(cstore::NativeLibaryKind, ~str)] {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_native_libraries(cdata)
}

pub fn each_impl(cstore: @cstore::CStore,
                 crate_num: ast::CrateNum,
                 callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::each_impl(cdata, callback)
}

pub fn each_implementation_for_type(cstore: @cstore::CStore,
                                    def_id: ast::DefId,
                                    callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::each_implementation_for_type(cdata, def_id.node, callback)
}

pub fn each_implementation_for_trait(cstore: @cstore::CStore,
                                     def_id: ast::DefId,
                                     callback: |ast::DefId|) {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::each_implementation_for_trait(cdata, def_id.node, callback)
}

/// If the given def ID describes a method belonging to a trait (either a
/// default method or an implementation of a trait method), returns the ID of
/// the trait that the method belongs to. Otherwise, returns `None`.
pub fn get_trait_of_method(cstore: @cstore::CStore,
                           def_id: ast::DefId,
                           tcx: ty::ctxt)
                           -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(def_id.crate);
    decoder::get_trait_of_method(cdata, def_id.node, tcx)
}

pub fn get_macro_registrar_fn(cstore: @cstore::CStore,
                              crate_num: ast::CrateNum)
                              -> Option<ast::DefId> {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_macro_registrar_fn(cdata)
}

pub fn get_exported_macros(cstore: @cstore::CStore,
                           crate_num: ast::CrateNum)
                           -> ~[@ast::Item] {
    let cdata = cstore.get_crate_data(crate_num);
    decoder::get_exported_macros(cdata)
}
<|endoftext|>


<commit_before><commit_msg>libxen: Add definition of set_trap_table()<commit_after>use defs::{TrapInfo, Ulong};

use hypercall::hypercall1;
use hypercall::HypercallKind;

pub unsafe fn set_trap_table(table: *const TrapInfo) {
    hypercall1(HypercallKind::SetTrapTable, table as Ulong);
}
<|endoftext|>


<commit_before>#![deny(rustdoc::broken_intra_doc_links)]

mod compiler_plugin;
mod customize;
mod gen;
mod map;
pub mod protoc_gen_rust;

use std::fs;
use std::io;
use std::path::Path;

pub use customize::Customize;
#[doc(hidden)]
pub use gen::paths::proto_name_to_rs;
use protobuf::descriptor::*;
use protobuf_parse::ProtoPathBuf;

use crate::gen::all::gen_all;

struct GenFileResult {
    compiler_plugin_result: compiler_plugin::GenResult,
    mod_name: String,
}

#[derive(Debug, thiserror::Error)]
enum Error {
    #[error("output path `{0}` is not a directory")]
    OutputIsNotDirectory(String),
    #[error("output path `{0}` does not exist or not accessible")]
    OutputDoesNotExistOrNotAccssible(String, #[source] io::Error),
    #[error("failed to create file `{0}`: {1}")]
    FailedToWriteFile(String, #[source] io::Error),
}

pub fn gen_and_write(
    file_descriptors: &[FileDescriptorProto],
    parser: &str,
    files_to_generate: &[ProtoPathBuf],
    out_dir: &Path,
    customize: &Customize,
) -> anyhow::Result<()> {
    match out_dir.metadata() {
        Ok(m) => {
            if !m.is_dir() {
                return Err(Error::OutputIsNotDirectory(out_dir.display().to_string()).into());
            }
        }
        Err(e) => {
            return Err(
                Error::OutputDoesNotExistOrNotAccssible(out_dir.display().to_string(), e).into(),
            );
        }
    }

    let results = gen_all(file_descriptors, parser, files_to_generate, customize)?;

    for r in &results {
        let mut file_path = out_dir.to_owned();
        file_path.push(&r.name);
        fs::write(&file_path, r.content.as_slice())
            .map_err(|e| Error::FailedToWriteFile(file_path.display().to_string(), e))?;
    }

    Ok(())
}
<commit_msg>Avoid using * import<commit_after>#![deny(rustdoc::broken_intra_doc_links)]

mod compiler_plugin;
mod customize;
mod gen;
mod map;
pub mod protoc_gen_rust;

use std::fs;
use std::io;
use std::path::Path;

pub use customize::Customize;
#[doc(hidden)]
pub use gen::paths::proto_name_to_rs;
use protobuf::descriptor::FileDescriptorProto;
use protobuf_parse::ProtoPathBuf;

use crate::gen::all::gen_all;

struct GenFileResult {
    compiler_plugin_result: compiler_plugin::GenResult,
    mod_name: String,
}

#[derive(Debug, thiserror::Error)]
enum Error {
    #[error("output path `{0}` is not a directory")]
    OutputIsNotDirectory(String),
    #[error("output path `{0}` does not exist or not accessible")]
    OutputDoesNotExistOrNotAccssible(String, #[source] io::Error),
    #[error("failed to create file `{0}`: {1}")]
    FailedToWriteFile(String, #[source] io::Error),
}

pub fn gen_and_write(
    file_descriptors: &[FileDescriptorProto],
    parser: &str,
    files_to_generate: &[ProtoPathBuf],
    out_dir: &Path,
    customize: &Customize,
) -> anyhow::Result<()> {
    match out_dir.metadata() {
        Ok(m) => {
            if !m.is_dir() {
                return Err(Error::OutputIsNotDirectory(out_dir.display().to_string()).into());
            }
        }
        Err(e) => {
            return Err(
                Error::OutputDoesNotExistOrNotAccssible(out_dir.display().to_string(), e).into(),
            );
        }
    }

    let results = gen_all(file_descriptors, parser, files_to_generate, customize)?;

    for r in &results {
        let mut file_path = out_dir.to_owned();
        file_path.push(&r.name);
        fs::write(&file_path, r.content.as_slice())
            .map_err(|e| Error::FailedToWriteFile(file_path.display().to_string(), e))?;
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate graph_match;
extern crate hyper;
extern crate rustc_serialize;

mod core_nlp;
mod graph_parser;

use graph_match::matching::EqualityRequirement;

fn matched_components_to_pattern(matched_components: &graph_match::matching::MatchedComponents, graph: &graph_match::graph::Graph) -> String {
    let mut pattern: Vec<(usize, String)> = Vec::new();

    for component in &matched_components.list {
        let mut label = String::new();
        match component.from_edge {
            Some(edge) => label.push_str(&graph.edges[edge].identifier.as_str()),
            None => label.push_str("root"),
        }
        label.push_str(".");
        match graph.nodes[component.node].attributes {
            Some(ref attrs) => {
                match attrs.get("lemma") {
                    Some(lemma) => label.push_str(lemma.as_str()),
                    None => label.push_str("BLANK"),
                }
            },
            None => label.push_str("BLANK"),
        }
        pattern.push((component.node, label));
    }

    pattern.sort_by(|a,b| a.0.cmp(&b.0));
    return pattern.iter().map(|e| e.1.clone() ).collect::<Vec<String>>().join(" ");
}

fn main() {
    let text = "The man ran home, the man eat the food.".to_string();
    let string_graphs = match core_nlp::graphs_for_text(&text) {
        Ok(graphs) => graphs,
        Err(message) => panic!("There was an error in building the graph string representation ({})", message),
    };

    let query_string = "type:node identifier:subj pos:NN\n\
                        type:node identifier:verb pos:VB\n\
                        type:node identifier:obj pos:NN\n\
                        type:edge identifier:subj source:1 target:0 label:nsubj\n\
                        type:edge identifier:obj source:1 target:2 label:dobj";
    let query = graph_parser::parse(&query_string.to_string()).unwrap();

    for g in string_graphs {
        println!("Graph:\n{}", g);
        let graph = match graph_parser::parse(&g) {
            Ok(g) => g,
            Err(message) => {
                println!("The following graph: {}, failed with the following message: {}", g, message);
                continue;
            }
        };

        let banned_edges: Vec<String> = vec!["advcl".to_string(), "csubj".to_string(), "ccomp".to_string(), "dep".to_string(), "parataxis".to_string()];
        println!("Points");
        for matched_components in graph_match::match_graph(&query, 1, &graph, &EqualityRequirement::Contains) {
            println!("{:?}", matched_components.list);
            println!("{:?}", matched_components_to_pattern(&matched_components, &graph));
            let root_node_index = matched_components.list[0].node;
            println!("{:?}", graph_match::expand_subgraph(&graph, root_node_index, &banned_edges));
        }
    }
}
<commit_msg>Implement extract presentation<commit_after>extern crate graph_match;
extern crate hyper;
extern crate rustc_serialize;

mod core_nlp;
mod graph_parser;

use graph_match::matching::EqualityRequirement;
use graph_match::graph::Graph;

fn matched_components_to_pattern(matched_components: &graph_match::matching::MatchedComponents, graph: &Graph) -> String {
    let mut pattern: Vec<(usize, String)> = Vec::new();

    for component in &matched_components.list {
        let mut label = String::new();
        match component.from_edge {
            Some(edge) => label.push_str(&graph.edges[edge].identifier.as_str()),
            None => label.push_str("root"),
        }
        label.push_str(".");
        match graph.nodes[component.node].attributes {
            Some(ref attrs) => {
                match attrs.get("lemma") {
                    Some(lemma) => label.push_str(lemma.as_str()),
                    None => label.push_str("BLANK"),
                }
            },
            None => label.push_str("BLANK"),
        }
        pattern.push((component.node, label));
    }

    pattern.sort_by(|a,b| a.0.cmp(&b.0));
    return pattern.iter().map(|e| e.1.clone() ).collect::<Vec<String>>().join(" ");
}

fn subgraph_nodes_to_extract_string(node_indexes: &Vec<usize>, graph: &Graph) -> String {
    let mut extract_string = String::new();
    let mut sorted_node_indexes = node_indexes.clone();
    sorted_node_indexes.sort_by(|a, b| a.cmp(b));
    for index in sorted_node_indexes {
        match graph.nodes[index].attributes {
            Some(ref attrs) => {
                match attrs.get("before") {
                    Some(value) => {
                        match value.as_str() {
                            "space" => extract_string.push_str(" "),
                            "empty" => extract_string.push_str(""),
                            "unknown" => extract_string.push_str("?"),
                            _ => extract_string.push_str("???"),
                        }
                    }
                    _ => {}
                }
                match attrs.get("word") {
                    Some(value) => extract_string.push_str(value.as_str()),
                    _ => {}
                }
                match attrs.get("after") {
                    Some(value) => {
                        match value.as_str() {
                            "space" => extract_string.push_str(" "),
                            "empty" => extract_string.push_str(""),
                            "unknown" => extract_string.push_str("?"),
                            _ => extract_string.push_str("???"),
                        }
                    }
                    _ => {}
                }
            },
            None => {}
        };
    }
    return extract_string.replace("  ", " ");
}

fn main() {
    let text = "The man ran home, the man eat the food.".to_string();
    let string_graphs = match core_nlp::graphs_for_text(&text) {
        Ok(graphs) => graphs,
        Err(message) => panic!("There was an error in building the graph string representation ({})", message),
    };

    let query_string = "type:node identifier:subj pos:NN\n\
                        type:node identifier:verb pos:VB\n\
                        type:node identifier:obj pos:NN\n\
                        type:edge identifier:subj source:1 target:0 label:nsubj\n\
                        type:edge identifier:obj source:1 target:2 label:dobj";
    let query = graph_parser::parse(&query_string.to_string()).unwrap();

    for g in string_graphs {
        println!("Graph:\n{}", g);
        let graph = match graph_parser::parse(&g) {
            Ok(g) => g,
            Err(message) => {
                println!("The following graph: {}, failed with the following message: {}", g, message);
                continue;
            }
        };

        let banned_edges: Vec<String> = vec!["advcl".to_string(), "csubj".to_string(), "ccomp".to_string(), "dep".to_string(), "parataxis".to_string()];
        println!("Points");
        for matched_components in graph_match::match_graph(&query, 1, &graph, &EqualityRequirement::Contains) {
            println!("{:?}", matched_components_to_pattern(&matched_components, &graph));
            let root_node_index = matched_components.list[0].node;
            let node_indexes = graph_match::expand_subgraph(&graph, root_node_index, &banned_edges);
            println!("{:?}", subgraph_nodes_to_extract_string(&node_indexes, &graph));
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This file is the Rust implementation of
//! [processor.ts](https://github.com/google/sxg-rs/blob/main/typescript_utilities/src/processor.ts).
//! Most of the context of why and how we process HTML are documented in that file.

use crate::http::HttpResponse;
use crate::http_parser::link::Link;
use crate::link::ALLOWED_PARAM_NAMES;
use anyhow::Result;
use serde::Deserialize;
use std::borrow::Cow;

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessHtmlOption {
    pub is_sxg: bool,
}

#[derive(Debug, PartialEq, Eq)]
enum ContentType {
    HtmlUtf8,
    HtmlOther,
    Other,
}
fn parse_content_type(content_type_header_value: &str) -> ContentType {
    let content_type_header_value = content_type_header_value.trim_start().to_ascii_lowercase();
    if content_type_header_value.starts_with("text/html") {
        if content_type_header_value.contains("utf-8") {
            ContentType::HtmlUtf8
        } else {
            ContentType::HtmlOther
        }
    } else {
        ContentType::Other
    }
}

/// Processes HTML using the following processors.
/// - For `<link rel=preload>` elements, they are promoted to Link headers.
/// - For `<template data-sxg-only>` elements:
///   - If SXG, they are "unwrapped" (i.e. their children are promoted out of the <template>).
///   - Else, they are deleted.
/// - For `<script data-issxg-var>` elements, they are replaced with
///   `<script>window.isSXG=...</script>`, where `...` is true or false.
/// If input charset is not UTF8, the input will be returned back without any modification.
pub fn process_html(input: HttpResponse, option: ProcessHtmlOption) -> Result<HttpResponse> {
    let content_type_header = input.headers.iter().find_map(|(name, value)| {
        if name.eq_ignore_ascii_case("content-type") {
            Some(value)
        } else {
            None
        }
    });
    let mut known_utf8 = false;
    if let Some(content_type_header) = content_type_header {
        match parse_content_type(content_type_header) {
            ContentType::HtmlUtf8 => known_utf8 = true,
            ContentType::HtmlOther => (),
            ContentType::Other => return Ok(input),
        };
    } else {
        // Doesn't process HTML because content-type header does not exsist.
        return Ok(input);
    }
    let input_body = match String::from_utf8(input.body) {
        Ok(input_body) => input_body,
        Err(e) => {
            // Doesn't process HTML because input body bytes can't be parsed at UTF-8 string, for
            // example, a UTF-16 BOM exsists.
            return Ok(HttpResponse {
                body: e.into_bytes(),
                headers: input.headers,
                status: input.status,
            });
        }
    };
    let mut link_headers: Vec<String> = vec![];
    let element_content_handlers = vec![
        // Parse the meta tag, per the implementation in HTMLMetaCharsetParser::CheckForMetaCharset:
        // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_meta_charset_parser.cc;l=62-125;drc=7a0b88f6d5c015fd3c280b58c7a99d8e1dca28ac.
        // This differs slightly from what's described at https://github.com/whatwg/html/issues/6962, and
        // differs drastically from what's specified in
        // https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding.
        lol_html::element!("meta", |e| {
            // EncodingFromMetaAttributes:
            // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_parser_idioms.cc;l=362-393;drc=7a0b88f6d5c015fd3c280b58c7a99d8e1dca28ac
            if let Some(charset) = e.get_attribute("charset") {
                if charset.eq_ignore_ascii_case("utf-8") {
                    known_utf8 = true;
                }
            } else if let (Some(http_equiv), Some(content)) =
                (e.get_attribute("http-equiv"), e.get_attribute("content"))
            {
                if http_equiv.eq_ignore_ascii_case("content-type")
                    && parse_content_type(&content) == ContentType::HtmlUtf8
                {
                    known_utf8 = true;
                }
            }
            Ok(())
        }),
        lol_html::element!(
            r#"link[rel~="preload" i][href][as]:not([data-sxg-no-header])"#,
            |e| {
                if let Some(href) = e.get_attribute("href") {
                    let params: Vec<(Cow<'static, str>, Option<String>)> = e
                        .attributes()
                        .iter()
                        .filter_map(|attr| {
                            let name = attr.name();
                            let value = attr.value();
                            if ALLOWED_PARAM_NAMES.contains(name.as_str()) {
                                Some((Cow::Owned(name), Some(value)))
                            } else {
                                None
                            }
                        })
                        .collect();
                    let link = Link { uri: href, params };
                    link_headers.push(link.serialize());
                }
                Ok(())
            }
        ),
        lol_html::element!(r#"script[data-issxg-var]"#, |e| {
            e.set_inner_content(
                &format!("window.isSXG={}", option.is_sxg),
                lol_html::html_content::ContentType::Html,
            );
            Ok(())
        }),
        lol_html::element!(r#"template[data-sxg-only]"#, |e| {
            if option.is_sxg {
                e.remove_and_keep_content()
            } else {
                e.remove()
            }
            Ok(())
        }),
    ];
    let output = lol_html::rewrite_str(
        &input_body,
        lol_html::Settings {
            element_content_handlers,
            ..lol_html::Settings::default()
        },
    )?;
    if !known_utf8 {
        return Ok(HttpResponse {
            headers: input.headers,
            status: input.status,
            body: input_body.into_bytes(),
        });
    }
    let mut output_headers = input.headers;
    output_headers.push(("Link".to_string(), link_headers.join(",")));
    Ok(HttpResponse {
        body: output.into_bytes(),
        headers: output_headers,
        status: input.status,
    })
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_parses_content_type() {
        assert_eq!(parse_content_type(r#"text/html"#), ContentType::HtmlOther);
        assert_eq!(
            parse_content_type(r#"text/html; charset=utf-8"#),
            ContentType::HtmlUtf8
        );
        assert_eq!(
            parse_content_type(r#"text/html; charset="utf-8""#),
            ContentType::HtmlUtf8
        );
        assert_eq!(
            parse_content_type(r#"text/html; charset=ascii"#),
            ContentType::HtmlOther
        );
        assert_eq!(parse_content_type(r#"text/plain"#), ContentType::Other);
    }
    fn quick_process(content_type: &str, input_body: &str) -> String {
        let output = process_html(
            HttpResponse {
                status: 200,
                headers: vec![("content-type".to_string(), content_type.to_string())],
                body: input_body.to_string().into_bytes(),
            },
            ProcessHtmlOption { is_sxg: true },
        );
        String::from_utf8(output.unwrap().body).unwrap()
    }
    #[test]
    fn it_works() {
        assert_eq!(
            quick_process(
                "text/html;charset=utf-8",
                "<script data-issxg-var></script>",
            ),
            "<script data-issxg-var>window.isSXG=true</script>"
        );
        // HTML is not processed when charset is not specified.
        assert_eq!(
            quick_process("text/html", "<script data-issxg-var></script>",),
            "<script data-issxg-var></script>",
        );
        // Meta tag of charset is supported.
        assert_eq!(
            quick_process(
                "text/html",
                "<meta http-equiv=content-type content=\"text/html;charset=utf-8\">\
                <script data-issxg-var></script>"
            ),
            "<meta http-equiv=content-type content=\"text/html;charset=utf-8\">\
            <script data-issxg-var>window.isSXG=true</script>"
        );
        // Meta tag with HTML-encoded attribute
        assert_eq!(
            quick_process(
                "text/html",
                "<meta http-equiv=content-type content=\"text/html;charset="utf-8"\">\
                <script data-issxg-var></script>"
            ),
            "<meta http-equiv=content-type content=\"text/html;charset="utf-8"\">\
            <script data-issxg-var>window.isSXG=true</script>",
        );
    }
}
<commit_msg>Update content-length header when processing html (#226)<commit_after>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This file is the Rust implementation of
//! [processor.ts](https://github.com/google/sxg-rs/blob/main/typescript_utilities/src/processor.ts).
//! Most of the context of why and how we process HTML are documented in that file.

use crate::http::HttpResponse;
use crate::http_parser::link::Link;
use crate::link::ALLOWED_PARAM_NAMES;
use anyhow::Result;
use serde::Deserialize;
use std::borrow::Cow;

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessHtmlOption {
    pub is_sxg: bool,
}

#[derive(Debug, PartialEq, Eq)]
enum ContentType {
    HtmlUtf8,
    HtmlOther,
    Other,
}
fn parse_content_type(content_type_header_value: &str) -> ContentType {
    let content_type_header_value = content_type_header_value.trim_start().to_ascii_lowercase();
    if content_type_header_value.starts_with("text/html") {
        if content_type_header_value.contains("utf-8") {
            ContentType::HtmlUtf8
        } else {
            ContentType::HtmlOther
        }
    } else {
        ContentType::Other
    }
}

/// Processes HTML using the following processors.
/// - For `<link rel=preload>` elements, they are promoted to Link headers.
/// - For `<template data-sxg-only>` elements:
///   - If SXG, they are "unwrapped" (i.e. their children are promoted out of the <template>).
///   - Else, they are deleted.
/// - For `<script data-issxg-var>` elements, they are replaced with
///   `<script>window.isSXG=...</script>`, where `...` is true or false.
/// - The `content-length` header is updated to the new value.
/// If input charset is not UTF8, the input will be returned back without any modification.
pub fn process_html(input: HttpResponse, option: ProcessHtmlOption) -> Result<HttpResponse> {
    let content_type_header = input.headers.iter().find_map(|(name, value)| {
        if name.eq_ignore_ascii_case("content-type") {
            Some(value)
        } else {
            None
        }
    });
    let mut known_utf8 = false;
    if let Some(content_type_header) = content_type_header {
        match parse_content_type(content_type_header) {
            ContentType::HtmlUtf8 => known_utf8 = true,
            ContentType::HtmlOther => (),
            ContentType::Other => return Ok(input),
        };
    } else {
        // Doesn't process HTML because content-type header does not exsist.
        return Ok(input);
    }
    let input_body = match String::from_utf8(input.body) {
        Ok(input_body) => input_body,
        Err(e) => {
            // Doesn't process HTML because input body bytes can't be parsed at UTF-8 string, for
            // example, a UTF-16 BOM exsists.
            return Ok(HttpResponse {
                body: e.into_bytes(),
                headers: input.headers,
                status: input.status,
            });
        }
    };
    let mut link_headers: Vec<String> = vec![];
    let element_content_handlers = vec![
        // Parse the meta tag, per the implementation in HTMLMetaCharsetParser::CheckForMetaCharset:
        // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_meta_charset_parser.cc;l=62-125;drc=7a0b88f6d5c015fd3c280b58c7a99d8e1dca28ac.
        // This differs slightly from what's described at https://github.com/whatwg/html/issues/6962, and
        // differs drastically from what's specified in
        // https://html.spec.whatwg.org/multipage/parsing.html#prescan-a-byte-stream-to-determine-its-encoding.
        lol_html::element!("meta", |e| {
            // EncodingFromMetaAttributes:
            // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/parser/html_parser_idioms.cc;l=362-393;drc=7a0b88f6d5c015fd3c280b58c7a99d8e1dca28ac
            if let Some(charset) = e.get_attribute("charset") {
                if charset.eq_ignore_ascii_case("utf-8") {
                    known_utf8 = true;
                }
            } else if let (Some(http_equiv), Some(content)) =
                (e.get_attribute("http-equiv"), e.get_attribute("content"))
            {
                if http_equiv.eq_ignore_ascii_case("content-type")
                    && parse_content_type(&content) == ContentType::HtmlUtf8
                {
                    known_utf8 = true;
                }
            }
            Ok(())
        }),
        lol_html::element!(
            r#"link[rel~="preload" i][href][as]:not([data-sxg-no-header])"#,
            |e| {
                if let Some(href) = e.get_attribute("href") {
                    let params: Vec<(Cow<'static, str>, Option<String>)> = e
                        .attributes()
                        .iter()
                        .filter_map(|attr| {
                            let name = attr.name();
                            let value = attr.value();
                            if ALLOWED_PARAM_NAMES.contains(name.as_str()) {
                                Some((Cow::Owned(name), Some(value)))
                            } else {
                                None
                            }
                        })
                        .collect();
                    let link = Link { uri: href, params };
                    link_headers.push(link.serialize());
                }
                Ok(())
            }
        ),
        lol_html::element!(r#"script[data-issxg-var]"#, |e| {
            e.set_inner_content(
                &format!("window.isSXG={}", option.is_sxg),
                lol_html::html_content::ContentType::Html,
            );
            Ok(())
        }),
        lol_html::element!(r#"template[data-sxg-only]"#, |e| {
            if option.is_sxg {
                e.remove_and_keep_content()
            } else {
                e.remove()
            }
            Ok(())
        }),
    ];
    let output = lol_html::rewrite_str(
        &input_body,
        lol_html::Settings {
            element_content_handlers,
            ..lol_html::Settings::default()
        },
    )?;
    if !known_utf8 {
        return Ok(HttpResponse {
            headers: input.headers,
            status: input.status,
            body: input_body.into_bytes(),
        });
    }
    let mut output_headers = input.headers;
    if !link_headers.is_empty() {
        output_headers.push(("Link".to_string(), link_headers.join(",")));
    }
    let output_body = output.into_bytes();
    for (name, value) in output_headers.iter_mut() {
        if name.eq_ignore_ascii_case("content-length") {
            *value = format!("{}", output_body.len());
        }
    }
    Ok(HttpResponse {
        body: output_body,
        headers: output_headers,
        status: input.status,
    })
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_parses_content_type() {
        assert_eq!(parse_content_type(r#"text/html"#), ContentType::HtmlOther);
        assert_eq!(
            parse_content_type(r#"text/html; charset=utf-8"#),
            ContentType::HtmlUtf8
        );
        assert_eq!(
            parse_content_type(r#"text/html; charset="utf-8""#),
            ContentType::HtmlUtf8
        );
        assert_eq!(
            parse_content_type(r#"text/html; charset=ascii"#),
            ContentType::HtmlOther
        );
        assert_eq!(parse_content_type(r#"text/plain"#), ContentType::Other);
    }
    fn quick_process(content_type: &str, input_body: &str) -> String {
        let output = process_html(
            HttpResponse {
                status: 200,
                headers: vec![("content-type".to_string(), content_type.to_string())],
                body: input_body.to_string().into_bytes(),
            },
            ProcessHtmlOption { is_sxg: true },
        );
        String::from_utf8(output.unwrap().body).unwrap()
    }
    #[test]
    fn it_processes_html() {
        assert_eq!(
            quick_process(
                "text/html;charset=utf-8",
                "<script data-issxg-var></script>",
            ),
            "<script data-issxg-var>window.isSXG=true</script>"
        );
        // HTML is not processed when charset is not specified.
        assert_eq!(
            quick_process("text/html", "<script data-issxg-var></script>",),
            "<script data-issxg-var></script>",
        );
        // Meta tag of charset is supported.
        assert_eq!(
            quick_process(
                "text/html",
                "<meta http-equiv=content-type content=\"text/html;charset=utf-8\">\
                <script data-issxg-var></script>"
            ),
            "<meta http-equiv=content-type content=\"text/html;charset=utf-8\">\
            <script data-issxg-var>window.isSXG=true</script>"
        );
        // Meta tag with HTML-encoded attribute
        assert_eq!(
            quick_process(
                "text/html",
                "<meta http-equiv=content-type content=\"text/html;charset="utf-8"\">\
                <script data-issxg-var></script>"
            ),
            "<meta http-equiv=content-type content=\"text/html;charset="utf-8"\">\
            <script data-issxg-var>window.isSXG=true</script>",
        );
        // HTTP content-length header is updated
        assert_eq!(
            process_html(
                HttpResponse {
                    status: 200,
                    headers: vec![
                        (
                            "content-type".to_string(),
                            "text/html;charset=utf-8".to_string()
                        ),
                        ("content-length".to_string(), "32".to_string()),
                    ],
                    body: "<script data-issxg-var></script>".to_string().into_bytes(),
                },
                ProcessHtmlOption { is_sxg: true },
            )
            .unwrap(),
            HttpResponse {
                status: 200,
                headers: vec![
                    (
                        "content-type".to_string(),
                        "text/html;charset=utf-8".to_string()
                    ),
                    ("content-length".to_string(), "49".to_string()),
                ],
                body: "<script data-issxg-var>window.isSXG=true</script>"
                    .to_string()
                    .into_bytes(),
            },
        );
    }
}
<|endoftext|>


<commit_before>use {Field, Borrowed, Value, Color, Matrix2d};
use {AddPolygons, View};
use {TweenPolygonsColorContext};
use vecmath::{identity};

/// An animation inbetweening context with color.
pub struct TweenColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
}

impl<'a> AddPolygons<'a, TweenPolygonsColorContext<'a>> for TweenColorContext<'a> {
    #[inline(always)]
    fn polygons(&'a self, polygons: &'a [&'a [f64]]) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Value(polygons),
        }
    }
}

impl<'a> View<'a> for TweenColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            tween_factor: Borrowed(self.tween_factor.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

<commit_msg>Sorted use alphabetically<commit_after>use {
    AddPolygons,
    Borrowed,
    Color,
    Field,
    Matrix2d,
    TweenPolygonsColorContext,
    Value,
    View,
};
use vecmath::{
    identity
};

/// An animation inbetweening context with color.
pub struct TweenColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
}

impl<'a> AddPolygons<'a, TweenPolygonsColorContext<'a>> for TweenColorContext<'a> {
    #[inline(always)]
    fn polygons(&'a self, polygons: &'a [&'a [f64]]) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Value(polygons),
        }
    }
}

impl<'a> View<'a> for TweenColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            tween_factor: Borrowed(self.tween_factor.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenColorContext<'a> {
        TweenColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

<|endoftext|>


<commit_before>use byteorder::{BigEndian,ReadBytesExt};
use sodiumoxide::crypto::hash::sha512::hash;
use std::io::Cursor;

pub fn sha512(input: &Vec<u8>) -> Vec<u8> {
    let digest = hash(&input[..]);

    let mut result = vec![];
    for &b in &digest[..] {
        result.push(b);
    }

    result
}

pub fn sha512_checksum(input: &Vec<u8>) -> u32 {
    let sha512 = sha512(input);

    assert!(sha512.len() >= 4);

    let mut cursor = Cursor::new(sha512);
    cursor.read_u32::<BigEndian>().unwrap()
}

<commit_msg>CG: Added a test covering two rounds of sha512 on the test string hello.<commit_after>use byteorder::{BigEndian,ReadBytesExt};
use sodiumoxide::crypto::hash::sha512::hash;
use std::io::Cursor;

pub fn sha512(input: &Vec<u8>) -> Vec<u8> {
    let digest = hash(&input[..]);

    let mut result = vec![];
    for &b in &digest[..] {
        result.push(b);
    }

    result
}

pub fn sha512_checksum(input: &Vec<u8>) -> u32 {
    let sha512 = sha512(input);

    assert!(sha512.len() >= 4);

    let mut cursor = Cursor::new(sha512);
    cursor.read_u32::<BigEndian>().unwrap()
}

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

    #[test]
    fn test_sha512() {
        let input: Vec<u8> = vec![ 104, 101, 108, 108, 111 ]; // hello]
        let output1 = sha512(&input);
        let output2 = sha512(&output1);

        let expected1 = vec![
                        0x9b, 0x71, 0xd2, 0x24, 0xbd, 0x62, 0xf3, 0x78,
                        0x5d, 0x96, 0xd4, 0x6a, 0xd3, 0xea, 0x3d, 0x73,
                        0x31, 0x9b, 0xfb, 0xc2, 0x89, 0x0c, 0xaa, 0xda,
                        0xe2, 0xdf, 0xf7, 0x25, 0x19, 0x67, 0x3c, 0xa7,
                        0x23, 0x23, 0xc3, 0xd9, 0x9b, 0xa5, 0xc1, 0x1d,
                        0x7c, 0x7a, 0xcc, 0x6e, 0x14, 0xb8, 0xc5, 0xda,
                        0x0c, 0x46, 0x63, 0x47, 0x5c, 0x2e, 0x5c, 0x3a,
                        0xde, 0xf4, 0x6f, 0x73, 0xbc, 0xde, 0xc0, 0x43 ];

        assert_eq!(expected1, output1);

        let expected2 = vec![
                        0x05, 0x92, 0xa1, 0x05, 0x84, 0xff, 0xab, 0xf9,
                        0x65, 0x39, 0xf3, 0xd7, 0x80, 0xd7, 0x76, 0x82,
                        0x8c, 0x67, 0xda, 0x1a, 0xb5, 0xb1, 0x69, 0xe9,
                        0xe8, 0xae, 0xd8, 0x38, 0xaa, 0xec, 0xc9, 0xed,
                        0x36, 0xd4, 0x9f, 0xf1, 0x42, 0x3c, 0x55, 0xf0,
                        0x19, 0xe0, 0x50, 0xc6, 0x6c, 0x63, 0x24, 0xf5,
                        0x35, 0x88, 0xbe, 0x88, 0x89, 0x4f, 0xef, 0x4d,
                        0xcf, 0xfd, 0xb7, 0x4b, 0x98, 0xe2, 0xb2, 0x00 ];

        assert_eq!(expected2, output2);
    }
}<|endoftext|>