<commit_before>use bot::LalafellBot;
use database::models::{ChannelConfig, NewChannelConfig, ServerConfig, NewServerConfig, Reaction, NewReaction};

use diesel;
use diesel::prelude::*;

use lalafell::error::*;
use lalafell::commands::prelude::*;
use lalafell::commands::ChannelOrId;

use discord::model::{permissions, Message, LiveServer, PublicChannel, UserId, ChannelId};

use lalafell::bot::Bot;

use std::sync::Arc;

const USAGE: &'static str = "!configure <subcommand/help>";

pub struct ConfigureCommand {
  bot: Arc<LalafellBot>
}

impl ConfigureCommand {
  pub fn new(bot: Arc<LalafellBot>) -> ConfigureCommand {
    ConfigureCommand {
      bot: bot
    }
  }

  fn help<'a>(&self) -> CommandResult<'a> {
    Ok("Help".into())
  }

  fn image_dump<'a>(&self, channel: ChannelId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    let config: Option<ChannelConfig> = ::bot::CONNECTION.with(|c| {
      use database::schema::channel_configs::dsl;
      dsl::channel_configs
        .filter(dsl::server_id.eq(server.id.0.to_string()).and(dsl::channel_id.eq(channel.to_string())))
        .first(c)
        .optional()
        .chain_err(|| "could not load channel configs")
    })?;
    if args.len() < 3 {
      let status = match config.and_then(|c| c.image_dump_allowed) {
        Some(true) => "enabled",
        Some(false) => "disabled",
        None => "unset (disabled)"
      };
      return Ok(format!("`!imagedump` status in {}: {}", channel.mention(), status).into());
    }
    let enabled = match args[2].to_lowercase().as_str() {
      "enabled" | "enable" | "on" | "true" | "yes" => true,
      "disabled" | "disable" | "off" | "false" | "no" => false,
      _ => return Err("Unknown enabled state provided".into())
    };
    match config {
      Some(conf) => {
        ::bot::CONNECTION.with(|c| {
          use database::schema::channel_configs::dsl;
          diesel::update(&conf)
            .set(dsl::image_dump_allowed.eq(Some(enabled)))
            .execute(c)
            .chain_err(|| "could not update config")
        })?;
      },
      None => {
        ::bot::CONNECTION.with(|c| {
          let new = NewChannelConfig {
            server_id: server.id.into(),
            channel_id: channel.into(),
            image_dump_allowed: Some(enabled)
          };
          diesel::insert(&new)
            .into(::database::schema::channel_configs::table)
            .execute(c)
            .chain_err(|| "could not add config")
        })?;
      }
    }
    Ok(format!("Set `!imagedump` status in {} to {}.", channel.mention(), if enabled { "enabled" } else { "disabled" }).into())
  }

  // FIXME: don't require channel subcommand
  fn reactions<'a>(&self, channel: ChannelId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if args.len() < 3 {
      let reactions: Vec<Reaction> = ::bot::CONNECTION.with(|c| {
        use database::schema::reactions::dsl;
        dsl::reactions.load(c).chain_err(|| "could not load reactions")
      })?;
      let strings: Vec<String> = reactions.iter()
        .map(|r| format!("{}. {} grants `{}` on {} in {}", r.id, r.emoji, r.role, *r.message_id, ChannelId(*r.channel_id).mention()))
        .collect();
      return Ok(strings.join("\n").into());
    }
    match args[2].to_lowercase().as_str() {
      "add" | "create" => {
        if args.len() < 6 {
          return Err("!configure channel [channel] reaction add [emoji] [messageID] [role]".into());
        }
        let emoji = &args[3];
        let message_id: u64 = args[4].parse().map_err(|_| into!(CommandFailure, "Invalid message ID."))?;
        let role = args[5..].join(" ").to_lowercase();
        let role = match server.roles.iter().find(|r| r.name.to_lowercase() == role) {
          Some(r) => r.name.clone(),
          None => return Err("No such role.".into())
        };
        let new_reaction = NewReaction {
          server_id: server.id.into(),
          channel_id: channel.into(),
          message_id: message_id.into(),
          emoji: emoji.to_string(),
          role: role
        };
        ::bot::CONNECTION.with(|c| {
          diesel::insert(&new_reaction)
            .into(::database::schema::reactions::table)
            .execute(c)
            .chain_err(|| "could not insert reaction")
        })?;
        Ok(CommandSuccess::default())
      },
      "remove" | "delete" => {
        if args.len() < 4 {
          return Err("!configure channel [channel] reaction remove [id]".into());
        }
        let id: i32 = args[3].parse().map_err(|_| into!(CommandFailure, "Invalid ID."))?;
        let affected = ::bot::CONNECTION.with(|c| {
          use database::schema::reactions::dsl;
          diesel::delete(dsl::reactions.filter(dsl::id.eq(id)))
            .execute(c)
            .chain_err(|| "could not delete reaction")
        })?;
        if affected > 0 {
          Ok(CommandSuccess::default())
        } else {
          Err("No reactions were deleted.".into())
        }
      },
      _ => Err("Invalid subcommand.".into())
    }
  }

  fn channel<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if args.len() < 2 {
      return Err("`!configure channel [channel] [subcommand]`".into());
    }
    let channel = ChannelOrId::parse(&args[0]).map_err(|_| into!(CommandFailure, "Invalid channel reference."))?;
    // FIXME: imagedump is manage messages, but reactions is manage roles
    let has_permissions = server.permissions_for(channel, author).contains(permissions::MANAGE_MESSAGES);
    if !has_permissions {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough permissions.")
          .description("You don't have enough permissions to use this command."))
        .wrap());
    }
    match args[1].to_lowercase().as_str() {
      "imagedump" | "image_dump" => self.image_dump(channel, server, args),
      "reaction" | "reactions" => self.reactions(channel, server, args),
      _ => return Err("Invalid subcommand.".into())
    }
  }

  fn server<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if args.is_empty() {
      return Err("`!configure server [subcommand]`".into());
    }
    if author != server.owner_id {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough permissions.")
          .description("You don't have enough permissions to use this command."))
        .wrap());
    }
    match args[0].to_lowercase().as_str() {
      "timeoutrole" | "timeout_role" => {} // TODO: move into separate methods,
      _ => return Err("Invalid subcommand.".into())
    }
    let config: Option<ServerConfig> = ::bot::CONNECTION.with(|c| {
      use database::schema::server_configs::dsl;
      dsl::server_configs
        .filter(dsl::server_id.eq(server.id.0.to_string()))
        .first(c)
        .optional()
        .chain_err(|| "could not load channel configs")
    })?;
    if args.len() < 2 {
      let status = match config.and_then(|c| c.timeout_role) {
        Some(role) => role,
        None => String::from("unset (disabled)")
      };
      return Ok(format!("Timeout role on {}: {}", server.name, status).into());
    }
    let role_name = args[1].to_lowercase();
    let role = match server.roles.iter().find(|r| r.name.to_lowercase() == role_name) {
      Some(r) => r,
      None => return Err(format!("No role by the name `{}`.", &args[2]).into())
    };
    match config {
      Some(conf) => {
        ::bot::CONNECTION.with(|c| {
          use database::schema::server_configs::dsl;
          diesel::update(&conf)
            .set(dsl::timeout_role.eq(Some(role.name.clone())))
            .execute(c)
            .chain_err(|| "could not update config")
        })?;
      },
      None => {
        ::bot::CONNECTION.with(|c| {
          let new = NewServerConfig {
            server_id: server.id.into(),
            timeout_role: Some(role.name.clone())
          };
          diesel::insert(&new)
            .into(::database::schema::server_configs::table)
            .execute(c)
            .chain_err(|| "could not add config")
        })?;
      }
    }
    Ok(format!("Set timeout role in {} to {}.", server.name, role.name).into())
  }
}

impl HasBot for ConfigureCommand {
  fn bot(&self) -> &Bot {
    self.bot.as_ref()
  }
}

#[derive(Debug, Deserialize)]
pub struct Params {
  subcommand: String,
  args: Option<Vec<String>>
}

impl HasParams for ConfigureCommand {
  type Params = Params;
}

impl<'a> PublicChannelCommand<'a> for ConfigureCommand {
  fn run(&self, message: &Message, server: &LiveServer, _: &PublicChannel, params: &[&str]) -> CommandResult<'a> {
    let params = self.params(USAGE, params)?;
    let args = params.args.unwrap_or_default();
    match params.subcommand.to_lowercase().as_str() {
      "help" => self.help(),
      "channel" => self.channel(message.author.id, server, &args),
      "server" => self.server(message.author.id, server, &args),
      _ => Err("No such subcommand. Try `help`.".into())
    }
  }
}
<commit_msg>refactor: move into separate methods and fix reactions<commit_after>use bot::LalafellBot;
use database::models::{ChannelConfig, NewChannelConfig, ServerConfig, NewServerConfig, Reaction, NewReaction};

use diesel;
use diesel::prelude::*;

use lalafell::error::*;
use lalafell::commands::prelude::*;
use lalafell::commands::ChannelOrId;

use discord::model::{permissions, Message, LiveServer, PublicChannel, UserId, ChannelId};

use lalafell::bot::Bot;

use std::sync::Arc;

const USAGE: &'static str = "!configure <subcommand/help>";

pub struct ConfigureCommand {
  bot: Arc<LalafellBot>
}

impl ConfigureCommand {
  pub fn new(bot: Arc<LalafellBot>) -> ConfigureCommand {
    ConfigureCommand {
      bot: bot
    }
  }

  fn help<'a>(&self) -> CommandResult<'a> {
    Ok("Help".into())
  }

  fn image_dump<'a>(&self, author: UserId, channel: ChannelId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if !server.permissions_for(channel, author).contains(permissions::MANAGE_MESSAGES) {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough permissions.")
          .description("You don't have enough permissions to use this command."))
        .wrap());
    }
    let config: Option<ChannelConfig> = ::bot::CONNECTION.with(|c| {
      use database::schema::channel_configs::dsl;
      dsl::channel_configs
        .filter(dsl::server_id.eq(server.id.0.to_string()).and(dsl::channel_id.eq(channel.to_string())))
        .first(c)
        .optional()
        .chain_err(|| "could not load channel configs")
    })?;
    if args.len() < 3 {
      let status = match config.and_then(|c| c.image_dump_allowed) {
        Some(true) => "enabled",
        Some(false) => "disabled",
        None => "unset (disabled)"
      };
      return Ok(format!("`!imagedump` status in {}: {}", channel.mention(), status).into());
    }
    let enabled = match args[2].to_lowercase().as_str() {
      "enabled" | "enable" | "on" | "true" | "yes" => true,
      "disabled" | "disable" | "off" | "false" | "no" => false,
      _ => return Err("Unknown enabled state provided".into())
    };
    match config {
      Some(conf) => {
        ::bot::CONNECTION.with(|c| {
          use database::schema::channel_configs::dsl;
          diesel::update(&conf)
            .set(dsl::image_dump_allowed.eq(Some(enabled)))
            .execute(c)
            .chain_err(|| "could not update config")
        })?;
      },
      None => {
        ::bot::CONNECTION.with(|c| {
          let new = NewChannelConfig {
            server_id: server.id.into(),
            channel_id: channel.into(),
            image_dump_allowed: Some(enabled)
          };
          diesel::insert(&new)
            .into(::database::schema::channel_configs::table)
            .execute(c)
            .chain_err(|| "could not add config")
        })?;
      }
    }
    Ok(format!("Set `!imagedump` status in {} to {}.", channel.mention(), if enabled { "enabled" } else { "disabled" }).into())
  }

  fn reactions<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if !server.permissions_for(server.id.main(), author).contains(permissions::MANAGE_ROLES) {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough permissions.")
          .description("You don't have enough permissions to use this command."))
        .wrap());
    }
    if args.len() < 2 {
      let reactions: Vec<Reaction> = ::bot::CONNECTION.with(|c| {
        use database::schema::reactions::dsl;
        dsl::reactions.load(c).chain_err(|| "could not load reactions")
      })?;
      let strings: Vec<String> = reactions.iter()
        .map(|r| format!("{}. {} grants `{}` on {} in {}", r.id, r.emoji, r.role, *r.message_id, ChannelId(*r.channel_id).mention()))
        .collect();
      return Ok(strings.join("\n").into());
    }
    match args[1].to_lowercase().as_str() {
      "add" | "create" => {
        if args.len() < 6 {
          return Err("!configure server reaction add [channel] [emoji] [messageID] [role]".into());
        }
        let channel = ChannelOrId::parse(&args[2]).map_err(|_| into!(CommandFailure, "Invalid channel reference."))?;
        let emoji = &args[3];
        let message_id: u64 = args[4].parse().map_err(|_| into!(CommandFailure, "Invalid message ID."))?;
        let role = args[5..].join(" ").to_lowercase();
        let role = match server.roles.iter().find(|r| r.name.to_lowercase() == role) {
          Some(r) => r.name.clone(),
          None => return Err("No such role.".into())
        };
        let new_reaction = NewReaction {
          server_id: server.id.into(),
          channel_id: channel.into(),
          message_id: message_id.into(),
          emoji: emoji.to_string(),
          role: role
        };
        ::bot::CONNECTION.with(|c| {
          diesel::insert(&new_reaction)
            .into(::database::schema::reactions::table)
            .execute(c)
            .chain_err(|| "could not insert reaction")
        })?;
        Ok(CommandSuccess::default())
      },
      "remove" | "delete" => {
        if args.len() < 3 {
          return Err("!configure server reaction remove [id]".into());
        }
        let id: i32 = args[2].parse().map_err(|_| into!(CommandFailure, "Invalid ID."))?;
        let affected = ::bot::CONNECTION.with(|c| {
          use database::schema::reactions::dsl;
          diesel::delete(dsl::reactions.filter(dsl::id.eq(id)))
            .execute(c)
            .chain_err(|| "could not delete reaction")
        })?;
        if affected > 0 {
          Ok(CommandSuccess::default())
        } else {
          Err("No reactions were deleted.".into())
        }
      },
      _ => Err("Invalid subcommand.".into())
    }
  }

  fn channel<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if args.len() < 2 {
      return Err("`!configure channel [channel] [subcommand]`".into());
    }
    let channel = ChannelOrId::parse(&args[0]).map_err(|_| into!(CommandFailure, "Invalid channel reference."))?;
    match args[1].to_lowercase().as_str() {
      "imagedump" | "image_dump" => self.image_dump(author, channel, server, args),
      _ => return Err("Invalid subcommand.".into())
    }
  }

  fn timeout_role<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if author != server.owner_id {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough permissions.")
          .description("You don't have enough permissions to use this command."))
        .wrap());
    }
    let config: Option<ServerConfig> = ::bot::CONNECTION.with(|c| {
      use database::schema::server_configs::dsl;
      dsl::server_configs
        .filter(dsl::server_id.eq(server.id.0.to_string()))
        .first(c)
        .optional()
        .chain_err(|| "could not load channel configs")
    })?;
    if args.len() < 2 {
      let status = match config.and_then(|c| c.timeout_role) {
        Some(role) => role,
        None => String::from("unset (disabled)")
      };
      return Ok(format!("Timeout role on {}: {}", server.name, status).into());
    }
    let role_name = args[1].to_lowercase();
    let role = match server.roles.iter().find(|r| r.name.to_lowercase() == role_name) {
      Some(r) => r,
      None => return Err(format!("No role by the name `{}`.", &args[2]).into())
    };
    match config {
      Some(conf) => {
        ::bot::CONNECTION.with(|c| {
          use database::schema::server_configs::dsl;
          diesel::update(&conf)
            .set(dsl::timeout_role.eq(Some(role.name.clone())))
            .execute(c)
            .chain_err(|| "could not update config")
        })?;
      },
      None => {
        ::bot::CONNECTION.with(|c| {
          let new = NewServerConfig {
            server_id: server.id.into(),
            timeout_role: Some(role.name.clone())
          };
          diesel::insert(&new)
            .into(::database::schema::server_configs::table)
            .execute(c)
            .chain_err(|| "could not add config")
        })?;
      }
    }
    Ok(format!("Set timeout role in {} to {}.", server.name, role.name).into())
  }

  fn server<'a>(&self, author: UserId, server: &LiveServer, args: &[String]) -> CommandResult<'a> {
    if args.is_empty() {
      return Err("`!configure server [subcommand]`".into());
    }
    match args[0].to_lowercase().as_str() {
      "reaction" | "reactions" => self.reactions(author, server, args),
      "timeoutrole" | "timeout_role" => self.timeout_role(author, server, args),
      _ => return Err("Invalid subcommand.".into())
    }
  }
}

impl HasBot for ConfigureCommand {
  fn bot(&self) -> &Bot {
    self.bot.as_ref()
  }
}

#[derive(Debug, Deserialize)]
pub struct Params {
  subcommand: String,
  args: Option<Vec<String>>
}

impl HasParams for ConfigureCommand {
  type Params = Params;
}

impl<'a> PublicChannelCommand<'a> for ConfigureCommand {
  fn run(&self, message: &Message, server: &LiveServer, _: &PublicChannel, params: &[&str]) -> CommandResult<'a> {
    let params = self.params(USAGE, params)?;
    let args = params.args.unwrap_or_default();
    match params.subcommand.to_lowercase().as_str() {
      "help" => self.help(),
      "channel" => self.channel(message.author.id, server, &args),
      "server" => self.server(message.author.id, server, &args),
      _ => Err("No such subcommand. Try `help`.".into())
    }
  }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::rc::Rc;

use dispatcher::request::{InternalRequest, RequestHandler};
use context::event::EventHandler;
use reactor;

pub struct TimerEventHandler {
    contexts: Vec<Rc<RefCell<Box<EventHandler<InternalRequest>>>>>,
}

impl TimerEventHandler {
    pub fn new() -> TimerEventHandler {
        TimerEventHandler {
            contexts: Vec::new(),
        }
    }

    pub fn register_handler(&mut self, handler: Rc<RefCell<Box<EventHandler<InternalRequest>>>>) {
        self.contexts.push(handler);
    }
}

impl reactor::EventHandler<InternalRequest> for TimerEventHandler {
    fn handle_event(&mut self, event: InternalRequest) {
            let event: InternalRequest = event.into();
            for i in self.contexts.iter_mut() {
                i.borrow_mut().handle_event(event.clone());
            }
    }
    fn handler(&self) -> RequestHandler {
        RequestHandler::Timer
    }
}
<commit_msg>TimerEventHandler: simplify handle_event()<commit_after>use std::cell::RefCell;
use std::rc::Rc;

use dispatcher::request::{InternalRequest, RequestHandler};
use context::event::EventHandler;
use reactor;

pub struct TimerEventHandler {
    contexts: Vec<Rc<RefCell<Box<EventHandler<InternalRequest>>>>>,
}

impl TimerEventHandler {
    pub fn new() -> TimerEventHandler {
        TimerEventHandler {
            contexts: Vec::new(),
        }
    }

    pub fn register_handler(&mut self, handler: Rc<RefCell<Box<EventHandler<InternalRequest>>>>) {
        self.contexts.push(handler);
    }
}

impl reactor::EventHandler<InternalRequest> for TimerEventHandler {
    fn handle_event(&mut self, event: InternalRequest) {
        for i in self.contexts.iter_mut() {
            i.borrow_mut().handle_event(event.clone());
        }
    }
    fn handler(&self) -> RequestHandler {
        RequestHandler::Timer
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 The Grin Developers
//
// 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
//
//     http://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.

//! Hash Function
//!
//! Primary hash function used in the protocol
//!

use byteorder::{BigEndian, ByteOrder};
use std::cmp::min;
use std::convert::AsRef;
use std::ops::Add;
use std::{fmt, ops};

use crate::blake2::blake2b::Blake2b;

use crate::ser::{self, AsFixedBytes, Error, FixedLength, Readable, Reader, Writeable, Writer};
use crate::util;

/// A hash consisting of all zeroes, used as a sentinel. No known preimage.
pub const ZERO_HASH: Hash = Hash([0; 32]);

/// A hash to uniquely (or close enough) identify one of the main blockchain
/// constructs. Used pervasively for blocks, transactions and outputs.
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct Hash([u8; 32]);

impl fmt::Debug for Hash {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		let hash_hex = self.to_hex();
		const NUM_SHOW: usize = 12;

		write!(f, "{}...", &hash_hex[..NUM_SHOW])
	}
}

impl fmt::Display for Hash {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		fmt::Debug::fmt(self, f)
	}
}

impl FixedLength for Hash {
	/// Size of a hash in bytes.
	const LEN: usize = 32;
}

impl Hash {
	/// Builds a Hash from a byte vector. If the vector is too short, it will be
	/// completed by zeroes. If it's too long, it will be truncated.
	pub fn from_vec(v: &[u8]) -> Hash {
		let mut h = [0; Hash::LEN];
		let copy_size = min(v.len(), Hash::LEN);
		h[..copy_size].copy_from_slice(&v[..copy_size]);
		Hash(h)
	}

	/// Converts the hash to a byte vector
	pub fn to_vec(&self) -> Vec<u8> {
		self.0.to_vec()
	}

	/// Returns a byte slice of the hash contents.
	pub fn as_bytes(&self) -> &[u8] {
		&self.0
	}

	/// Convert a hash to hex string format.
	pub fn to_hex(&self) -> String {
		util::to_hex(self.to_vec())
	}

	/// Convert hex string back to hash.
	pub fn from_hex(hex: &str) -> Result<Hash, Error> {
		let bytes = util::from_hex(hex.to_string())
			.map_err(|_| Error::HexError(format!("failed to decode {}", hex)))?;
		Ok(Hash::from_vec(&bytes))
	}

	/// Most significant 64 bits
	pub fn to_u64(&self) -> u64 {
		BigEndian::read_u64(&self.0)
	}
}

impl ops::Index<usize> for Hash {
	type Output = u8;

	fn index(&self, idx: usize) -> &u8 {
		&self.0[idx]
	}
}

impl ops::Index<ops::Range<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::Range<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeTo<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeTo<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeFrom<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeFrom<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeFull> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeFull) -> &[u8] {
		&self.0[idx]
	}
}

impl AsRef<[u8]> for Hash {
	fn as_ref(&self) -> &[u8] {
		&self.0
	}
}

impl Readable for Hash {
	fn read(reader: &mut dyn Reader) -> Result<Hash, ser::Error> {
		let v = reader.read_fixed_bytes(32)?;
		let mut a = [0; 32];
		a.copy_from_slice(&v[..]);
		Ok(Hash(a))
	}
}

impl Writeable for Hash {
	fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
		writer.write_fixed_bytes(&self.0)
	}
}

impl Add for Hash {
	type Output = Hash;
	fn add(self, other: Hash) -> Hash {
		self.hash_with(other)
	}
}

impl Default for Hash {
	fn default() -> Hash {
		ZERO_HASH
	}
}

/// Serializer that outputs a hash of the serialized object
pub struct HashWriter {
	state: Blake2b,
}

impl HashWriter {
	/// Consume the `HashWriter`, outputting its current hash into a 32-byte
	/// array
	pub fn finalize(self, output: &mut [u8]) {
		output.copy_from_slice(self.state.finalize().as_bytes());
	}

	/// Consume the `HashWriter`, outputting a `Hash` corresponding to its
	/// current state
	pub fn into_hash(self) -> Hash {
		let mut res = [0; 32];
		res.copy_from_slice(self.state.finalize().as_bytes());
		Hash(res)
	}
}

impl Default for HashWriter {
	fn default() -> HashWriter {
		HashWriter {
			state: Blake2b::new(32),
		}
	}
}

impl ser::Writer for HashWriter {
	fn serialization_mode(&self) -> ser::SerializationMode {
		ser::SerializationMode::Hash
	}

	fn write_fixed_bytes<T: AsFixedBytes>(&mut self, b32: &T) -> Result<(), ser::Error> {
		self.state.update(b32.as_ref());
		Ok(())
	}
}

/// A trait for types that have a canonical hash
pub trait Hashed {
	/// Obtain the hash of the object
	fn hash(&self) -> Hash;
	/// Hash the object together with another writeable object
	fn hash_with<T: Writeable>(&self, other: T) -> Hash;
}

impl<W: ser::Writeable> Hashed for W {
	fn hash(&self) -> Hash {
		let mut hasher = HashWriter::default();
		ser::Writeable::write(self, &mut hasher).unwrap();
		let mut ret = [0; 32];
		hasher.finalize(&mut ret);
		Hash(ret)
	}

	fn hash_with<T: Writeable>(&self, other: T) -> Hash {
		let mut hasher = HashWriter::default();
		ser::Writeable::write(self, &mut hasher).unwrap();
		ser::Writeable::write(&other, &mut hasher).unwrap();
		let mut ret = [0; 32];
		hasher.finalize(&mut ret);
		Hash(ret)
	}
}
<commit_msg>Remvoe 3 dots from hash formatting<commit_after>// Copyright 2018 The Grin Developers
//
// 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
//
//     http://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.

//! Hash Function
//!
//! Primary hash function used in the protocol
//!

use byteorder::{BigEndian, ByteOrder};
use std::cmp::min;
use std::convert::AsRef;
use std::ops::Add;
use std::{fmt, ops};

use crate::blake2::blake2b::Blake2b;

use crate::ser::{self, AsFixedBytes, Error, FixedLength, Readable, Reader, Writeable, Writer};
use crate::util;

/// A hash consisting of all zeroes, used as a sentinel. No known preimage.
pub const ZERO_HASH: Hash = Hash([0; 32]);

/// A hash to uniquely (or close enough) identify one of the main blockchain
/// constructs. Used pervasively for blocks, transactions and outputs.
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct Hash([u8; 32]);

impl fmt::Debug for Hash {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		let hash_hex = self.to_hex();
		const NUM_SHOW: usize = 12;

		write!(f, "{}", &hash_hex[..NUM_SHOW])
	}
}

impl fmt::Display for Hash {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		fmt::Debug::fmt(self, f)
	}
}

impl FixedLength for Hash {
	/// Size of a hash in bytes.
	const LEN: usize = 32;
}

impl Hash {
	/// Builds a Hash from a byte vector. If the vector is too short, it will be
	/// completed by zeroes. If it's too long, it will be truncated.
	pub fn from_vec(v: &[u8]) -> Hash {
		let mut h = [0; Hash::LEN];
		let copy_size = min(v.len(), Hash::LEN);
		h[..copy_size].copy_from_slice(&v[..copy_size]);
		Hash(h)
	}

	/// Converts the hash to a byte vector
	pub fn to_vec(&self) -> Vec<u8> {
		self.0.to_vec()
	}

	/// Returns a byte slice of the hash contents.
	pub fn as_bytes(&self) -> &[u8] {
		&self.0
	}

	/// Convert a hash to hex string format.
	pub fn to_hex(&self) -> String {
		util::to_hex(self.to_vec())
	}

	/// Convert hex string back to hash.
	pub fn from_hex(hex: &str) -> Result<Hash, Error> {
		let bytes = util::from_hex(hex.to_string())
			.map_err(|_| Error::HexError(format!("failed to decode {}", hex)))?;
		Ok(Hash::from_vec(&bytes))
	}

	/// Most significant 64 bits
	pub fn to_u64(&self) -> u64 {
		BigEndian::read_u64(&self.0)
	}
}

impl ops::Index<usize> for Hash {
	type Output = u8;

	fn index(&self, idx: usize) -> &u8 {
		&self.0[idx]
	}
}

impl ops::Index<ops::Range<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::Range<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeTo<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeTo<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeFrom<usize>> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeFrom<usize>) -> &[u8] {
		&self.0[idx]
	}
}

impl ops::Index<ops::RangeFull> for Hash {
	type Output = [u8];

	fn index(&self, idx: ops::RangeFull) -> &[u8] {
		&self.0[idx]
	}
}

impl AsRef<[u8]> for Hash {
	fn as_ref(&self) -> &[u8] {
		&self.0
	}
}

impl Readable for Hash {
	fn read(reader: &mut dyn Reader) -> Result<Hash, ser::Error> {
		let v = reader.read_fixed_bytes(32)?;
		let mut a = [0; 32];
		a.copy_from_slice(&v[..]);
		Ok(Hash(a))
	}
}

impl Writeable for Hash {
	fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
		writer.write_fixed_bytes(&self.0)
	}
}

impl Add for Hash {
	type Output = Hash;
	fn add(self, other: Hash) -> Hash {
		self.hash_with(other)
	}
}

impl Default for Hash {
	fn default() -> Hash {
		ZERO_HASH
	}
}

/// Serializer that outputs a hash of the serialized object
pub struct HashWriter {
	state: Blake2b,
}

impl HashWriter {
	/// Consume the `HashWriter`, outputting its current hash into a 32-byte
	/// array
	pub fn finalize(self, output: &mut [u8]) {
		output.copy_from_slice(self.state.finalize().as_bytes());
	}

	/// Consume the `HashWriter`, outputting a `Hash` corresponding to its
	/// current state
	pub fn into_hash(self) -> Hash {
		let mut res = [0; 32];
		res.copy_from_slice(self.state.finalize().as_bytes());
		Hash(res)
	}
}

impl Default for HashWriter {
	fn default() -> HashWriter {
		HashWriter {
			state: Blake2b::new(32),
		}
	}
}

impl ser::Writer for HashWriter {
	fn serialization_mode(&self) -> ser::SerializationMode {
		ser::SerializationMode::Hash
	}

	fn write_fixed_bytes<T: AsFixedBytes>(&mut self, b32: &T) -> Result<(), ser::Error> {
		self.state.update(b32.as_ref());
		Ok(())
	}
}

/// A trait for types that have a canonical hash
pub trait Hashed {
	/// Obtain the hash of the object
	fn hash(&self) -> Hash;
	/// Hash the object together with another writeable object
	fn hash_with<T: Writeable>(&self, other: T) -> Hash;
}

impl<W: ser::Writeable> Hashed for W {
	fn hash(&self) -> Hash {
		let mut hasher = HashWriter::default();
		ser::Writeable::write(self, &mut hasher).unwrap();
		let mut ret = [0; 32];
		hasher.finalize(&mut ret);
		Hash(ret)
	}

	fn hash_with<T: Writeable>(&self, other: T) -> Hash {
		let mut hasher = HashWriter::default();
		ser::Writeable::write(self, &mut hasher).unwrap();
		ser::Writeable::write(&other, &mut hasher).unwrap();
		let mut ret = [0; 32];
		hasher.finalize(&mut ret);
		Hash(ret)
	}
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use color::ColorAlpha;
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

/// The forward compositor.
///
/// This compositor is a very simple one: it forwards a render to the screen. It can also create an
/// empty render – it basically cleans the screen with the color of your choice.
pub struct Forward {
  framebuffer: Framebuffer<Flat, Dim2, (), ()>,
  program: Res<Program>,
  quad: Tess
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      framebuffer: Framebuffer::default((w, h)),
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
    }
  }

  /// Display a texture onto screen.
  pub fn texture_screen(&self, source: &Texture2D<RGBA32F>) {
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&self.framebuffer, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }

  /// Render a black screen to screen.
  pub fn black_screen(&self, clear_color: ColorAlpha) {
    Pipeline::new(&self.framebuffer, *clear_color.as_ref(), &[], &[], vec![]).run();
  }
}
<commit_msg>Updated renderers of spectra.<commit_after>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use color::ColorAlpha;
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

/// The forward compositor.
///
/// This compositor is a very simple one: it forwards a render to the screen. It can also create an
/// empty render – it basically cleans the screen with the color of your choice.
pub struct Forward {
  framebuffer: Framebuffer<Flat, Dim2, (), ()>,
  program: Res<Program>,
  quad: Tess
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      framebuffer: Framebuffer::default((w, h)),
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
    }
  }

  /// Display a texture onto screen.
  pub fn texture_screen(&self, source: &Texture2D<RGBA32F>) {
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&self.framebuffer, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }

  /// Render a screen to screen with a given color.
  pub fn color_screen(&self, clear_color: ColorAlpha) {
    Pipeline::new(&self.framebuffer, *clear_color.as_ref(), &[], &[], vec![]).run();
  }
}
<|endoftext|>


<commit_before>extern crate regex;
extern crate chrono;

use std::io::{self, BufRead};
use std::collections::HashMap;
use std::fmt;
use chrono::prelude::*;

fn code1() {
    let stdin = io::stdin();

    let mut lines = stdin.lock().lines().fuse();
    let input = match lines.next()  {
        Some(Ok(a))  => a,
        _ => panic!("Couldn t read input.")
    };

    let info = input.trim();
    let splitted = info.split(",");
    let iter = splitted.map(|a| a.to_string().parse().unwrap_or(0));

    let mut result  = 0;
    for num in iter {
        result += num;
    }
    println!("{:?}", result);
}

fn code2() {
    let mut threes = 0;
    let mut two = 0;
    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }

    let mut saved_characters: HashMap<String, i32> = HashMap::new();
    for info in &vec {
        for charact in info.to_string().chars()  {
            let value = saved_characters.entry(charact.to_string()).or_insert(0);
            *value += 1;
        }

        let temp_threes = saved_characters.values().filter(|val| **val == 3).count();
        let temp_two = saved_characters.values().filter(|val| **val == 2).count();

        threes += temp_threes;
        two += temp_two;
    }
    println!("------------------------------");
    println!("threes: {}", threes);
    println!("twos: {}", two);
}

static DEFAULT: i32 = 0;
static MULTIPLE:  i32 = -1;

fn paint_matrix(matrix: &mut [[i32; 10]; 10]) {
    for (i, row) in  matrix.iter_mut().enumerate() {
        for (y, col) in row.iter_mut().enumerate() {
             if *col == 0 as i32 {
                print!(".");
             } else if *col == -1 as i32 {
                print!("X");
             } else {
                print!("{}", col);
             }
        }
        println!();
    }
}

fn fill_matrix(matrix: &mut [[i32; 10]; 10], entry: &mut Entry) {
    for x in entry.index_x..entry.width{
        for y in entry.index_y..entry.height {
            let current_value = matrix[x as usize][y as usize];
            if current_value == DEFAULT {
                 matrix[x as usize][y as usize] = entry.num;
                 //matrix[x as usize][y as usize] = "1";
            } else {
                if current_value != MULTIPLE {
                    matrix[x as usize][y as usize] = MULTIPLE;
                }
            }
        }
    }
}

pub struct Entry {
    num: i32,
    index_x: i32,
    index_y: i32,
    width: i32,
    height: i32
}

impl fmt::Display for Entry {
    fn fmt(&self,fmt:  &mut fmt::Formatter) -> fmt::Result {
        let str_num = "num=".to_string()+&self.num.to_string();
        let str_index_x = "index_x=".to_string() + &self.index_x.to_string();
        let str_index_y = "index_y=".to_string() + &self.index_y.to_string();
        let str_w = "w=".to_string() + &self.width.to_string();
        let str_h = "h=".to_string() + &self.height.to_string();
        let parsed = str_num + " " + str_index_x.as_str() + " " +  str_index_y.as_str() + " " +  str_w.as_str() + " " +  str_h.as_str();
        fmt.write_str(parsed.as_str())?;
        Ok(())
    }
}

fn code3() {
    use regex::Regex;
    let re = Regex::new(r"^#(\d) @ (\d),(\d): (\d)x(\d)").unwrap();
    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }
    // check input
    let mut entries: Vec<Entry> = Vec::new();
    for line in vec {
        println!("{:?}", re.is_match(line.as_str()));
        for cap in re.captures_iter(line.as_str()) {
            let num: i32 = cap[1].parse::<i32>().unwrap();
            let index_x: i32 = cap[2].parse::<i32>().unwrap();
            let index_y: i32 = cap[3].parse::<i32>().unwrap();
            let width: i32 = cap[4].parse::<i32>().unwrap();
            let height: i32 = cap[5].parse::<i32>().unwrap();
            let entry = Entry{num, index_x, index_y, width, height};
            entries.push(entry);
        }
    }

    let mut matrix = [[DEFAULT; 10];10];

    for mut ent in entries {
        println!("{}",ent);
        fill_matrix(&mut matrix, &mut ent);
    }

    paint_matrix(&mut matrix);

}

#[derive(PartialEq, Clone)]
enum Event {
    Shift,
    Asleep,
    Wakeup
}

pub struct SoldierEvent {
    event: Event,
    num_worker: i32,
    dt: DateTime<Utc>
}
impl SoldierEvent  {
    fn new( event: Event, num_worker: i32, year: i32, month: i32, day: i32, hour: i32, minutes: i32) -> SoldierEvent {
        let dt = Utc.ymd(year, month as u32, day as u32).and_hms(hour as u32, minutes as u32, 0);
        SoldierEvent {event: event, num_worker: num_worker,  dt: dt}
    }

}

pub struct Soldier {
    events: Vec<SoldierEvent>
}

impl Soldier {
    fn addEvent(& mut self, event: SoldierEvent) {
        self.events.push(event);
    }

}

fn code4 () {
    use regex::Regex;
    let mut re_shift = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] Guard #(\d{2}) begins shift").unwrap();
    let mut re_fall_sleeps = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] falls asleep").unwrap();
    let mut re_wakes_up = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] wakes up").unwrap();

    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }
    // check input
    let mut entries: Vec<SoldierEvent> = Vec::new();
    for line in vec {
        let mut current_soldier = -1;
        let typ: Event;
        let re;
        if (re_shift.is_match(line.as_str())) {
           re = re_shift.clone();
           typ = Event::Shift;
        } else if (re_fall_sleeps.is_match(line.as_str())) {
           re = re_fall_sleeps.clone();
           typ = Event::Asleep;
        } else {
           re = re_wakes_up.clone();
           typ = Event::Wakeup;
        }

        for cap in re.captures_iter(line.as_str()) {
            let year: i32 = cap[1].parse::<i32>().unwrap();
            let month: i32 = cap[2].parse::<i32>().unwrap();
            let day: i32 = cap[3].parse::<i32>().unwrap();
            let hour: i32 = cap[4].parse::<i32>().unwrap();
            let minutes: i32 = cap[5].parse::<i32>().unwrap();
            if(typ == Event::Shift) {
                current_soldier = cap[6].parse::<i32>().unwrap();
            }
            entries.push(SoldierEvent::new(typ.clone(), current_soldier, year, month, day, hour, minutes));
        }
    }
    println!("events {:}", entries.len());

    //TODO Finish code to search best sentynel
}

fn main() {
    //code1();
    //code2();
    //code3();
    code4();
}
<commit_msg>Added code for day 4<commit_after>extern crate regex;
extern crate chrono;

use std::io::{self, BufRead};
use std::collections::HashMap;
use std::fmt;
use chrono::prelude::*;

fn code1() {
    let stdin = io::stdin();

    let mut lines = stdin.lock().lines().fuse();
    let input = match lines.next()  {
        Some(Ok(a))  => a,
        _ => panic!("Couldn t read input.")
    };

    let info = input.trim();
    let splitted = info.split(",");
    let iter = splitted.map(|a| a.to_string().parse().unwrap_or(0));

    let mut result  = 0;
    for num in iter {
        result += num;
    }
    println!("{:?}", result);
}

fn code2() {
    let mut threes = 0;
    let mut two = 0;
    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }

    let mut saved_characters: HashMap<String, i32> = HashMap::new();
    for info in &vec {
        for charact in info.to_string().chars()  {
            let value = saved_characters.entry(charact.to_string()).or_insert(0);
            *value += 1;
        }

        let temp_threes = saved_characters.values().filter(|val| **val == 3).count();
        let temp_two = saved_characters.values().filter(|val| **val == 2).count();

        threes += temp_threes;
        two += temp_two;
    }
    println!("------------------------------");
    println!("threes: {}", threes);
    println!("twos: {}", two);
}

static DEFAULT: i32 = 0;
static MULTIPLE:  i32 = -1;

fn paint_matrix(matrix: &mut [[i32; 10]; 10]) {
    for (i, row) in  matrix.iter_mut().enumerate() {
        for (y, col) in row.iter_mut().enumerate() {
             if *col == 0 as i32 {
                print!(".");
             } else if *col == -1 as i32 {
                print!("X");
             } else {
                print!("{}", col);
             }
        }
        println!();
    }
}

fn fill_matrix(matrix: &mut [[i32; 10]; 10], entry: &mut Entry) {
    for x in entry.index_x..entry.width{
        for y in entry.index_y..entry.height {
            let current_value = matrix[x as usize][y as usize];
            if current_value == DEFAULT {
                 matrix[x as usize][y as usize] = entry.num;
                 //matrix[x as usize][y as usize] = "1";
            } else {
                if current_value != MULTIPLE {
                    matrix[x as usize][y as usize] = MULTIPLE;
                }
            }
        }
    }
}

pub struct Entry {
    num: i32,
    index_x: i32,
    index_y: i32,
    width: i32,
    height: i32
}

impl fmt::Display for Entry {
    fn fmt(&self,fmt:  &mut fmt::Formatter) -> fmt::Result {
        let str_num = "num=".to_string()+&self.num.to_string();
        let str_index_x = "index_x=".to_string() + &self.index_x.to_string();
        let str_index_y = "index_y=".to_string() + &self.index_y.to_string();
        let str_w = "w=".to_string() + &self.width.to_string();
        let str_h = "h=".to_string() + &self.height.to_string();
        let parsed = str_num + " " + str_index_x.as_str() + " " +  str_index_y.as_str() + " " +  str_w.as_str() + " " +  str_h.as_str();
        fmt.write_str(parsed.as_str())?;
        Ok(())
    }
}

fn code3() {
    use regex::Regex;
    let re = Regex::new(r"^#(\d) @ (\d),(\d): (\d)x(\d)").unwrap();
    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }
    // check input
    let mut entries: Vec<Entry> = Vec::new();
    for line in vec {
        println!("{:?}", re.is_match(line.as_str()));
        for cap in re.captures_iter(line.as_str()) {
            let num: i32 = cap[1].parse::<i32>().unwrap();
            let index_x: i32 = cap[2].parse::<i32>().unwrap();
            let index_y: i32 = cap[3].parse::<i32>().unwrap();
            let width: i32 = cap[4].parse::<i32>().unwrap();
            let height: i32 = cap[5].parse::<i32>().unwrap();
            let entry = Entry{num, index_x, index_y, width, height};
            entries.push(entry);
        }
    }

    let mut matrix = [[DEFAULT; 10];10];

    for mut ent in entries {
        println!("{}",ent);
        fill_matrix(&mut matrix, &mut ent);
    }

    paint_matrix(&mut matrix);

}

#[derive(PartialEq, Clone)]
enum Event {
    Shift,
    Asleep,
    Wakeup
}

#[derive(PartialEq, Clone)]
pub struct SleepEvent  {
    start_sleep: i64,
    stop_sleep: i64,
    quantity: i32
}

pub struct Soldier {
    num: i32,
    status: Event,
    start_sleep: Option<DateTime<Utc>>,
    events: Vec<SleepEvent>
}

impl Soldier {
    fn new(num: i32) -> Soldier {
        Soldier{ num: num, status: Event::Wakeup, start_sleep: None, events: Vec::new()}
    }

    fn add_event(& mut self, event: Event, year: i32, month: i32, day: i32, hour: i32, minutes: i32) {
        println!("id: {}", self.num);
        let dt = Utc.ymd(year, month as u32, day as u32).and_hms(hour as u32, minutes as u32, 0);
     //   self.events.push(event);
        match  event {
            Event::Asleep => {
                println!("Asleep {}", dt.timestamp());
                self.start_sleep = Some(dt);
            },
            Event::Wakeup => {
                let stop_sleep = dt;
                let quantity = (stop_sleep.timestamp() - self.start_sleep.unwrap().timestamp()) as i32;
                let sleepEvent: SleepEvent = SleepEvent{start_sleep: self.start_sleep.unwrap().timestamp(), stop_sleep: stop_sleep.timestamp(), quantity: quantity};
                self.events.push(sleepEvent);
            },
            _ => {
                println!("Other event");
            }
        }
    }
    fn contains_event(&mut self, moment_sleep: i32) -> Option<SleepEvent> {
        let bestSleep = self.events.iter().filter(|x| x.start_sleep >= moment_sleep as i64 || x.stop_sleep <= moment_sleep as i64).min_by_key(|x| x.quantity);
        match bestSleep {
            Some(x) => return Some(x.clone()),
            None => return None
        }
    }
}

fn code4 () {

    use regex::Regex;
    let mut re_shift = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] Guard #(\d{2}) begins shift").unwrap();
    let mut re_fall_sleeps = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] falls asleep").unwrap();
    let mut re_wakes_up = Regex::new(r"^\[(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})\] wakes up").unwrap();

    let mut vec: Vec<String> = Vec::new();

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let str_line = line.unwrap().trim().to_string();
        if str_line == "0" {
            println!("exit!");
            break;
        }
        vec.push(str_line);
    }
    // check input
    //let mut entries: Vec<SoldierEvent> = Vec::new();

    let mut soldiers: HashMap<i32, Soldier> = HashMap::new();

    let mut current_soldier = -1;
    for line in vec {
        let typ: Event;
        let re;
        if (re_shift.is_match(line.as_str())) {
           re = re_shift.clone();
           typ = Event::Shift;
        } else if (re_fall_sleeps.is_match(line.as_str())) {
           re = re_fall_sleeps.clone();
           typ = Event::Asleep;
        } else {
           re = re_wakes_up.clone();
           typ = Event::Wakeup;
        }

        for cap in re.captures_iter(line.as_str()) {
            let year: i32 = cap[1].parse::<i32>().unwrap();
            let month: i32 = cap[2].parse::<i32>().unwrap();
            let day: i32 = cap[3].parse::<i32>().unwrap();
            let hour: i32 = cap[4].parse::<i32>().unwrap();
            let minutes: i32 = cap[5].parse::<i32>().unwrap();
            if(typ == Event::Shift) {
                current_soldier = cap[6].parse::<i32>().unwrap();
                soldiers.entry(current_soldier).or_insert(Soldier::new(current_soldier));
            }
            let soldier = soldiers.get_mut(&current_soldier).unwrap();
            soldier.add_event(typ.clone(), year, month, day, hour, minutes);
        }
    }

    //TODO Finish code to search best sentynel
}

fn main() {
    //code1();
    //code2();
    //code3();
    code4();
}
<|endoftext|>


<commit_before>use crate::ops::{Deref, DerefMut};
use crate::ptr;

/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
///
/// This wrapper is 0-cost.
///
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
/// about all values being initialized at their type.  In particular, initializing
/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
///
/// # Examples
///
/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
/// the type:
///
/// ```rust
/// use std::mem::ManuallyDrop;
/// struct Peach;
/// struct Banana;
/// struct Melon;
/// struct FruitBox {
///     // Immediately clear there’s something non-trivial going on with these fields.
///     peach: ManuallyDrop<Peach>,
///     melon: Melon, // Field that’s independent of the other two.
///     banana: ManuallyDrop<Banana>,
/// }
///
/// impl Drop for FruitBox {
///     fn drop(&mut self) {
///         unsafe {
///             // Explicit ordering in which field destructors are run specified in the intuitive
///             // location – the destructor of the structure containing the fields.
///             // Moreover, one can now reorder fields within the struct however much they want.
///             ManuallyDrop::drop(&mut self.peach);
///             ManuallyDrop::drop(&mut self.banana);
///         }
///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
///     }
/// }
/// ```
///
/// [`mem::zeroed`]: fn.zeroed.html
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> {
    value: T,
}

impl<T> ManuallyDrop<T> {
    /// Wrap a value to be manually dropped.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// ManuallyDrop::new(Box::new(()));
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn new(value: T) -> ManuallyDrop<T> {
        ManuallyDrop { value }
    }

    /// Extracts the value from the `ManuallyDrop` container.
    ///
    /// This allows the value to be dropped again.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// let x = ManuallyDrop::new(Box::new(()));
    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
        slot.value
    }

    /// Takes the contained value out.
    ///
    /// This method is primarily intended for moving out values in drop.
    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
    /// you can use this method to take the value and use it however desired.
    /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
    ///
    /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function semantically moves out the contained value without preventing further usage.
    /// It is up to the user of this method to ensure that this container is not used again.
    ///
    /// [`ManuallyDrop::drop`]: #method.drop
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
    #[unstable(feature = "manually_drop_take", issue = "55422")]
    #[inline]
    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
        ManuallyDrop::into_inner(ptr::read(slot))
    }
}

impl<T: ?Sized> ManuallyDrop<T> {
    /// Manually drops the contained value.
    ///
    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function runs the destructor of the contained value and thus the wrapped value
    /// now represents uninitialized data. It is up to the user of this method to ensure the
    /// uninitialized data is not actually used.
    /// In particular, this function can only be called called at most once
    /// for a given instance of `ManuallyDrop<T>`.
    ///
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[inline]
    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
        ptr::drop_in_place(&mut slot.value)
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> Deref for ManuallyDrop<T> {
    type Target = T;
    #[inline(always)]
    fn deref(&self) -> &T {
        &self.value
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value
    }
}
<commit_msg>Typo fix<commit_after>use crate::ops::{Deref, DerefMut};
use crate::ptr;

/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
///
/// This wrapper is 0-cost.
///
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
/// about all values being initialized at their type.  In particular, initializing
/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
///
/// # Examples
///
/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
/// the type:
///
/// ```rust
/// use std::mem::ManuallyDrop;
/// struct Peach;
/// struct Banana;
/// struct Melon;
/// struct FruitBox {
///     // Immediately clear there’s something non-trivial going on with these fields.
///     peach: ManuallyDrop<Peach>,
///     melon: Melon, // Field that’s independent of the other two.
///     banana: ManuallyDrop<Banana>,
/// }
///
/// impl Drop for FruitBox {
///     fn drop(&mut self) {
///         unsafe {
///             // Explicit ordering in which field destructors are run specified in the intuitive
///             // location – the destructor of the structure containing the fields.
///             // Moreover, one can now reorder fields within the struct however much they want.
///             ManuallyDrop::drop(&mut self.peach);
///             ManuallyDrop::drop(&mut self.banana);
///         }
///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
///     }
/// }
/// ```
///
/// [`mem::zeroed`]: fn.zeroed.html
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> {
    value: T,
}

impl<T> ManuallyDrop<T> {
    /// Wrap a value to be manually dropped.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// ManuallyDrop::new(Box::new(()));
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn new(value: T) -> ManuallyDrop<T> {
        ManuallyDrop { value }
    }

    /// Extracts the value from the `ManuallyDrop` container.
    ///
    /// This allows the value to be dropped again.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// let x = ManuallyDrop::new(Box::new(()));
    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
        slot.value
    }

    /// Takes the contained value out.
    ///
    /// This method is primarily intended for moving out values in drop.
    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
    /// you can use this method to take the value and use it however desired.
    /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
    ///
    /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function semantically moves out the contained value without preventing further usage.
    /// It is up to the user of this method to ensure that this container is not used again.
    ///
    /// [`ManuallyDrop::drop`]: #method.drop
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
    #[unstable(feature = "manually_drop_take", issue = "55422")]
    #[inline]
    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
        ManuallyDrop::into_inner(ptr::read(slot))
    }
}

impl<T: ?Sized> ManuallyDrop<T> {
    /// Manually drops the contained value.
    ///
    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function runs the destructor of the contained value and thus the wrapped value
    /// now represents uninitialized data. It is up to the user of this method to ensure the
    /// uninitialized data is not actually used.
    /// In particular, this function can only be called at most once
    /// for a given instance of `ManuallyDrop<T>`.
    ///
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[inline]
    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
        ptr::drop_in_place(&mut slot.value)
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> Deref for ManuallyDrop<T> {
    type Target = T;
    #[inline(always)]
    fn deref(&self) -> &T {
        &self.value
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value
    }
}
<|endoftext|>


<commit_before>use std::str::Chars;

/// Peekable iterator over a char sequence.
///
/// Next characters can be peeked via `nth_char` method,
/// and position can be shifted forward via `bump` method.
pub(crate) struct Cursor<'a> {
    initial_len: usize,
    chars: Chars<'a>,
    #[cfg(debug_assertions)]
    prev: char,
}

pub(crate) const EOF_CHAR: char = '\0';

impl<'a> Cursor<'a> {
    pub(crate) fn new(input: &'a str) -> Cursor<'a> {
        Cursor {
            initial_len: input.len(),
            chars: input.chars(),
            #[cfg(debug_assertions)]
            prev: EOF_CHAR,
        }
    }

    /// For debug assertions only
    /// Returns the last eaten symbol (or '\0' in release builds).
    pub(crate) fn prev(&self) -> char {
        #[cfg(debug_assertions)]
        {
            self.prev
        }

        #[cfg(not(debug_assertions))]
        {
            '\0'
        }
    }

    /// Returns nth character relative to the current cursor position.
    /// If requested position doesn't exist, `EOF_CHAR` is returned.
    /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
    /// it should be checked with `is_eof` method.
    pub(crate) fn nth_char(&self, n: usize) -> char {
        self.chars().nth(n).unwrap_or(EOF_CHAR)
    }

    /// Peeks the next symbol from the input stream without consuming it.
    pub(crate) fn first(&self) -> char {
        self.nth_char(0)
    }

    /// Peeks the second symbol from the input stream without consuming it.
    pub(crate) fn second(&self) -> char {
        self.nth_char(1)
    }

    /// Checks if there is nothing more to consume.
    pub(crate) fn is_eof(&self) -> bool {
        self.chars.as_str().is_empty()
    }

    /// Returns amount of already consumed symbols.
    pub(crate) fn len_consumed(&self) -> usize {
        self.initial_len - self.chars.as_str().len()
    }

    /// Returns a `Chars` iterator over the remaining characters.
    fn chars(&self) -> Chars<'a> {
        self.chars.clone()
    }

    /// Moves to the next character.
    pub(crate) fn bump(&mut self) -> Option<char> {
        let c = self.chars.next()?;

        #[cfg(debug_assertions)]
        {
            self.prev = c;
        }

        Some(c)
    }
}
<commit_msg>librustc_lexer: Make nth_char method private<commit_after>use std::str::Chars;

/// Peekable iterator over a char sequence.
///
/// Next characters can be peeked via `nth_char` method,
/// and position can be shifted forward via `bump` method.
pub(crate) struct Cursor<'a> {
    initial_len: usize,
    chars: Chars<'a>,
    #[cfg(debug_assertions)]
    prev: char,
}

pub(crate) const EOF_CHAR: char = '\0';

impl<'a> Cursor<'a> {
    pub(crate) fn new(input: &'a str) -> Cursor<'a> {
        Cursor {
            initial_len: input.len(),
            chars: input.chars(),
            #[cfg(debug_assertions)]
            prev: EOF_CHAR,
        }
    }

    /// For debug assertions only
    /// Returns the last eaten symbol (or '\0' in release builds).
    pub(crate) fn prev(&self) -> char {
        #[cfg(debug_assertions)]
        {
            self.prev
        }

        #[cfg(not(debug_assertions))]
        {
            '\0'
        }
    }

    /// Returns nth character relative to the current cursor position.
    /// If requested position doesn't exist, `EOF_CHAR` is returned.
    /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
    /// it should be checked with `is_eof` method.
    fn nth_char(&self, n: usize) -> char {
        self.chars().nth(n).unwrap_or(EOF_CHAR)
    }

    /// Peeks the next symbol from the input stream without consuming it.
    pub(crate) fn first(&self) -> char {
        self.nth_char(0)
    }

    /// Peeks the second symbol from the input stream without consuming it.
    pub(crate) fn second(&self) -> char {
        self.nth_char(1)
    }

    /// Checks if there is nothing more to consume.
    pub(crate) fn is_eof(&self) -> bool {
        self.chars.as_str().is_empty()
    }

    /// Returns amount of already consumed symbols.
    pub(crate) fn len_consumed(&self) -> usize {
        self.initial_len - self.chars.as_str().len()
    }

    /// Returns a `Chars` iterator over the remaining characters.
    fn chars(&self) -> Chars<'a> {
        self.chars.clone()
    }

    /// Moves to the next character.
    pub(crate) fn bump(&mut self) -> Option<char> {
        let c = self.chars.next()?;

        #[cfg(debug_assertions)]
        {
            self.prev = c;
        }

        Some(c)
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix typo, thanks @chances!<commit_after><|endoftext|>


<commit_before>/* io::mod.rs */

use core::mem::volatile_store;
use kernel::sgash;

mod font;

/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/BBABEGGE.html */
pub static UART0: *mut u32 = 0x101f1000 as *mut u32;

pub static UART0_IMSC: *mut u32 = (0x101f1000 + 0x038) as *mut u32;
#[allow(dead_code)]
pub static VIC_INTENABLE: *mut u32 = (0x10140000 + 0x010) as *mut u32;

pub static mut CURSOR_X: u32 = 0;
pub static mut CURSOR_Y: u32 = 0;
pub static CURSOR_HEIGHT: u32 = 16;
pub static CURSOR_WIDTH: u32 = 8;
pub static mut CURSOR_COLOR: u32 = 0x000000FF;
pub static mut FG_COLOR: u32 = 0x00FFFFFF;
pub static mut BG_COLOR: u32 = 0xF0000000;
pub static mut CURSOR_BUFFER: [u32, ..8*16] = [0x00FF0000, ..8*16];
pub static mut SAVE_X: u32 = 0;
pub static mut SAVE_Y: u32 = 0;
pub static START_ADDR: u32 = 1024*1024;
pub static mut SCREEN_WIDTH: u32 = 0;
pub static mut SCREEN_HEIGHT: u32 = 0;

pub unsafe fn init(width: u32, height: u32)
{
	SCREEN_WIDTH = width;
	SCREEN_HEIGHT= height;
	sgash::init();

	/* For the following magic values, see
	 * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACHEDGD.html
	 */

	// 800x600
	// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACCCFBF.html
	if (SCREEN_WIDTH == 800 && SCREEN_HEIGHT == 600) {
		ws(0x10000010, 0x2CAC);
		ws(0x10120000, 0x1313A4C4);
		ws(0x10120004, 0x0505F657);
		ws(0x10120008, 0x071F1800);

		/* See http://forum.osdev.org/viewtopic.php?p=195000 */
		ws(0x10120010, START_ADDR);

		/* See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0161e/I911024.html */
		ws(0x10120018, 0x82B);
	}

	// 640x480
	// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACCCFBF.html
	else if (SCREEN_WIDTH == 640 && SCREEN_HEIGHT == 480) {
		ws(0x10000010, 0x2C77);
		ws(0x10120000, 0x3F1F3F9C);
		ws(0x10120004, 0x090B61DF);
		ws(0x10120008, 0x067F1800);

		/* See http://forum.osdev.org/viewtopic.php?p=195000 */
		ws(0x10120010, START_ADDR);

		/* See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0161e/I911024.html */
		ws(0x10120018, 0x82B);
	}
	set_bg(0x000000);
	set_fg(0xFAFCFF);
	set_cursor_color(0xFAFCFF);
	fill_bg();
	sgash::drawstr(&"sgash> ");
	draw_cursor();
}

pub unsafe fn write_char(c: char, address: *mut u32) {
	volatile_store(address, c as u32);
}

pub unsafe fn scrollup()
{
	let mut i = CURSOR_HEIGHT*SCREEN_WIDTH;
	while i < (SCREEN_WIDTH*SCREEN_HEIGHT) {
		*((START_ADDR + ((i-16*SCREEN_WIDTH)*4)) as *mut u32) = *((START_ADDR+(i*4)) as *u32);
		i += 1;
	}
	i = 4*(SCREEN_WIDTH*SCREEN_HEIGHT - CURSOR_HEIGHT*SCREEN_WIDTH);
	while i < 4*SCREEN_WIDTH*SCREEN_HEIGHT {
		*((START_ADDR + (i as u32)) as *mut u32) = BG_COLOR;
		i += 4;
	}
	CURSOR_X = 0x0u32;
	CURSOR_Y -= CURSOR_HEIGHT;
}
pub unsafe fn draw_char(c: char)
{
	if CURSOR_X+(SCREEN_WIDTH*CURSOR_Y) >= SCREEN_WIDTH*SCREEN_HEIGHT
	{
	scrollup();
	}
	let font_offset = (c as u8) - 0x20;
	let map = font::bitmaps[font_offset];

	let mut i = -1;
	let mut j = 0;
	let mut addr = START_ADDR + 4*(CURSOR_X + CURSOR_WIDTH + 1 + SCREEN_WIDTH*CURSOR_Y);
	while j < CURSOR_HEIGHT {
		while i < CURSOR_WIDTH {
			//let addr = START_ADDR + 4*(CURSOR_X + CURSOR_WIDTH - i + SCREEN_WIDTH*(CURSOR_Y + j));
			//let addr = START_ADDR + 4*(CURSOR_X + CURSOR_WIDTH + SCREEN_WIDTH*CURSOR_Y) - 4*i + 4*SCREEN_WIDTH*j
			if ((map[j] >> 4*i) & 1) == 1 {
				*(addr as *mut u32) = FG_COLOR;
			}
			else {
				*(addr as *mut u32) = BG_COLOR;
			}

			addr-= 4;
			i += 1;
		}
		addr += 4*(i+SCREEN_WIDTH);
		i = 0;
		j += 1;
	}
}

pub unsafe fn backup()
{
	let mut i = 0;
	let mut j = 0;
	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(CURSOR_X + i + SCREEN_WIDTH*(CURSOR_Y + j));
			CURSOR_BUFFER[i + j*8] = *(addr as *mut u32);
			i += 1;
		}
		i = 0;
		j += 1;
	}
	SAVE_X = CURSOR_X;
	SAVE_Y = CURSOR_Y;
}

pub unsafe fn restore()
{
	let mut i = 0;
	let mut j = 0;
	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(SAVE_X + i + SCREEN_WIDTH*(SAVE_Y + j));
			*(addr as *mut u32) = CURSOR_BUFFER[i + j*8];
			i += 1;
		}
		i = 0;
		j += 1;
	}
}

pub unsafe fn draw_cursor()
{

	let mut i = 0;
	let mut j = 0;

	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(CURSOR_X + i + SCREEN_WIDTH*(CURSOR_Y + j));
			*(addr as *mut u32) = CURSOR_COLOR;
			i += 1;
		}
		i = 0;
		j += 1;
	}

}

pub unsafe fn paint(color: u32)
{
	let mut i = 0;
	while i < SCREEN_WIDTH*SCREEN_HEIGHT
	{
		*((START_ADDR as u32 + i*4) as *mut u32) = color;
		i+=1;
	}
}

pub unsafe fn fill_bg()
{
	paint(BG_COLOR);
}

#[allow(dead_code)]
pub unsafe fn read(addr: u32)	->	u32
{
	*(addr as *mut u32)
}

pub unsafe fn ws(addr: u32, value: u32)
{
	*(addr as *mut u32) = *(addr as *mut u32) | value;
}

#[allow(dead_code)]
pub unsafe fn wh(addr: u32, value: u32)
{
	*(addr as *mut u32) = value;
}

pub unsafe fn set_fg(color: u32)
{
	FG_COLOR = color;
}

pub unsafe fn set_bg(color: u32)
{
	BG_COLOR = color;
}

pub unsafe fn set_cursor_color(color: u32)
{
	CURSOR_COLOR = color;
}
<commit_msg>Changed kernel to print all characters upside down<commit_after>/* io::mod.rs */

use core::mem::volatile_store;
use kernel::sgash;

mod font;

/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/BBABEGGE.html */
pub static UART0: *mut u32 = 0x101f1000 as *mut u32;

pub static UART0_IMSC: *mut u32 = (0x101f1000 + 0x038) as *mut u32;
#[allow(dead_code)]
pub static VIC_INTENABLE: *mut u32 = (0x10140000 + 0x010) as *mut u32;

pub static mut CURSOR_X: u32 = 0;
pub static mut CURSOR_Y: u32 = 0;
pub static CURSOR_HEIGHT: u32 = 16;
pub static CURSOR_WIDTH: u32 = 8;
pub static mut CURSOR_COLOR: u32 = 0x000000FF;
pub static mut FG_COLOR: u32 = 0x00FFFFFF;
pub static mut BG_COLOR: u32 = 0xF0000000;
pub static mut CURSOR_BUFFER: [u32, ..8*16] = [0x00FF0000, ..8*16];
pub static mut SAVE_X: u32 = 0;
pub static mut SAVE_Y: u32 = 0;
pub static START_ADDR: u32 = 1024*1024;
pub static mut SCREEN_WIDTH: u32 = 0;
pub static mut SCREEN_HEIGHT: u32 = 0;

pub unsafe fn init(width: u32, height: u32)
{
	SCREEN_WIDTH = width;
	SCREEN_HEIGHT= height;
	sgash::init();

	/* For the following magic values, see
	 * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACHEDGD.html
	 */

	// 800x600
	// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACCCFBF.html
	if (SCREEN_WIDTH == 800 && SCREEN_HEIGHT == 600) {
		ws(0x10000010, 0x2CAC);
		ws(0x10120000, 0x1313A4C4);
		ws(0x10120004, 0x0505F657);
		ws(0x10120008, 0x071F1800);

		/* See http://forum.osdev.org/viewtopic.php?p=195000 */
		ws(0x10120010, START_ADDR);

		/* See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0161e/I911024.html */
		ws(0x10120018, 0x82B);
	}

	// 640x480
	// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0225d/CACCCFBF.html
	else if (SCREEN_WIDTH == 640 && SCREEN_HEIGHT == 480) {
		ws(0x10000010, 0x2C77);
		ws(0x10120000, 0x3F1F3F9C);
		ws(0x10120004, 0x090B61DF);
		ws(0x10120008, 0x067F1800);

		/* See http://forum.osdev.org/viewtopic.php?p=195000 */
		ws(0x10120010, START_ADDR);

		/* See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0161e/I911024.html */
		ws(0x10120018, 0x82B);
	}
	set_bg(0x000000);
	set_fg(0xFAFCFF);
	set_cursor_color(0xFAFCFF);
	fill_bg();
	sgash::drawstr(&"sgash> ");
	draw_cursor();
}

pub unsafe fn write_char(c: char, address: *mut u32) {
	volatile_store(address, c as u32);
}

pub unsafe fn scrollup()
{
	let mut i = CURSOR_HEIGHT*SCREEN_WIDTH;
	while i < (SCREEN_WIDTH*SCREEN_HEIGHT) {
		*((START_ADDR + ((i-16*SCREEN_WIDTH)*4)) as *mut u32) = *((START_ADDR+(i*4)) as *u32);
		i += 1;
	}
	i = 4*(SCREEN_WIDTH*SCREEN_HEIGHT - CURSOR_HEIGHT*SCREEN_WIDTH);
	while i < 4*SCREEN_WIDTH*SCREEN_HEIGHT {
		*((START_ADDR + (i as u32)) as *mut u32) = BG_COLOR;
		i += 4;
	}
	CURSOR_X = 0x0u32;
	CURSOR_Y -= CURSOR_HEIGHT;
}
pub unsafe fn draw_char(c: char)
{
	if CURSOR_X+(SCREEN_WIDTH*CURSOR_Y) >= SCREEN_WIDTH*SCREEN_HEIGHT
	{
	scrollup();
	}
	let font_offset = (c as u8) - 0x20;
	let map = font::bitmaps[font_offset];

	let mut i = -1;
	let mut j = 0;
	let mut addr = START_ADDR + 4*(CURSOR_X + /*CURSOR_WIDTH +*/ 1 + SCREEN_WIDTH*CURSOR_Y + CURSOR_HEIGHT*SCREEN_WIDTH);
	while j < CURSOR_HEIGHT {
		while i < CURSOR_WIDTH {
			//let addr = START_ADDR + 4*(CURSOR_X + CURSOR_WIDTH - i + SCREEN_WIDTH*(CURSOR_Y + j));
			//let addr = START_ADDR + 4*(CURSOR_X + CURSOR_WIDTH + SCREEN_WIDTH*CURSOR_Y) - 4*i + 4*SCREEN_WIDTH*j
			if ((map[j] >> 4*i) & 1) == 1 {
				*(addr as *mut u32) = FG_COLOR;
			}
			else {
				*(addr as *mut u32) = BG_COLOR;
			}

			addr+= 4;
			i += 1;
		}
		addr -= 4*(SCREEN_WIDTH+i);
		i = 0;
		j += 1;
	}
}

pub unsafe fn backup()
{
	let mut i = 0;
	let mut j = 0;
	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(CURSOR_X + i + SCREEN_WIDTH*(CURSOR_Y + j));
			CURSOR_BUFFER[i + j*8] = *(addr as *mut u32);
			i += 1;
		}
		i = 0;
		j += 1;
	}
	SAVE_X = CURSOR_X;
	SAVE_Y = CURSOR_Y;
}

pub unsafe fn restore()
{
	let mut i = 0;
	let mut j = 0;
	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(SAVE_X + i + SCREEN_WIDTH*(SAVE_Y + j));
			*(addr as *mut u32) = CURSOR_BUFFER[i + j*8];
			i += 1;
		}
		i = 0;
		j += 1;
	}
}

pub unsafe fn draw_cursor()
{

	let mut i = 0;
	let mut j = 0;

	while j < CURSOR_HEIGHT
	{
		while i < CURSOR_WIDTH
		{
			let addr = START_ADDR + 4*(CURSOR_X + i + SCREEN_WIDTH*(CURSOR_Y + j));
			*(addr as *mut u32) = CURSOR_COLOR;
			i += 1;
		}
		i = 0;
		j += 1;
	}

}

pub unsafe fn paint(color: u32)
{
	let mut i = 0;
	while i < SCREEN_WIDTH*SCREEN_HEIGHT
	{
		*((START_ADDR as u32 + i*4) as *mut u32) = color;
		i+=1;
	}
}

pub unsafe fn fill_bg()
{
	paint(BG_COLOR);
}

#[allow(dead_code)]
pub unsafe fn read(addr: u32)	->	u32
{
	*(addr as *mut u32)
}

pub unsafe fn ws(addr: u32, value: u32)
{
	*(addr as *mut u32) = *(addr as *mut u32) | value;
}

#[allow(dead_code)]
pub unsafe fn wh(addr: u32, value: u32)
{
	*(addr as *mut u32) = value;
}

pub unsafe fn set_fg(color: u32)
{
	FG_COLOR = color;
}

pub unsafe fn set_bg(color: u32)
{
	BG_COLOR = color;
}

pub unsafe fn set_cursor_color(color: u32)
{
	CURSOR_COLOR = color;
}
<|endoftext|>