<commit_before>extern crate hkg;
extern crate rustbox;
extern crate rustc_serialize;

use std::default::Default;

use rustbox::{Color, RustBox};
use rustbox::Key;

use rustc_serialize::json;

use hkg::utility::cache;
use hkg::model::TopicItem;

fn main() {

    loop {
        // GUI init
        let rustbox = match RustBox::init(Default::default()) {
            Result::Ok(v) => v,
            Result::Err(e) => panic!("{}", e),
        };

        let w = rustbox.width();
        let h = rustbox.height();
        let title = String::from("高登");
        print_header(&rustbox, w, title);

        let s = cache::readfile(String::from("topics.json"));
        let collection: Vec<TopicItem> = json::decode(&s).unwrap();

        print_body(&rustbox, w, 2, h - 3, collection);

        rustbox.print(1,
                      h - 1,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      "Press 'q' to quit.");

        rustbox.present();
        match rustbox.poll_event(false) {
            Ok(rustbox::Event::KeyEvent(key)) => {
                match key {
                    Key::Char('q') => {
                        break;
                    }
                    _ => {}
                }
            }
            Err(e) => panic!("{}", e),
            _ => {}
        }
    }
}

fn print_header(rustbox: &rustbox::RustBox, width: usize, text: String) {
    let padding = (width - text.len()) / 2;
    let header_bottom = (0..width).map(|_| "─").collect::<Vec<_>>().join("");
    rustbox.print(padding,
                  0,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  &text);
    rustbox.print(0,
                  1,
                  rustbox::RB_BOLD,
                  Color::Yellow,
                  Color::Black,
                  &header_bottom);
}

fn print_body(rustbox: &rustbox::RustBox,
              width: usize,
              offset_x: usize,
              rows: usize,
              collection: Vec<TopicItem>) {

    for (i, item) in collection.iter().take(rows).enumerate() {
        rustbox.print(0,
                      i + offset_x,
                      rustbox::RB_NORMAL,
                      Color::White,
                      Color::Black,
                      &format!("[{no:0>2}] {title}",
                               no = i + 1,
                               title = item.titles[0].text));

        rustbox.print(width - 12 - 3,
                      i + offset_x,
                      rustbox::RB_NORMAL,
                      Color::White,
                      Color::Black,
                      &format!("| {author}", author = &item.author.name));
    }
}

// fn debug_load_and_print_topics() {
//     let s = cache::readfile(String::from("topics.json"));
//     let collection: Vec<TopicItem> = json::decode(&s).unwrap();
//
//     println!("topics {:?}", collection.len());
//     debug_print_topics(collection);
// }
//
// fn debug_print_topics(collection: Vec<TopicItem>) {
//     for (i, item) in collection.iter().enumerate() {
//
//         println!("item[{}]= {title} {author_name} {last_replied_date} {last_replied_time} \
//                   {reply_count} {rating}",
//                  i,
//                  title = item.titles[0].text,
//                  author_name = item.author.name,
//                  last_replied_date = item.last_replied_date,
//                  last_replied_time = item.last_replied_time,
//                  reply_count = item.reply_count,
//                  rating = item.rating);
//     }
// }
<commit_msg>truncate title if it is too long<commit_after>extern crate hkg;
extern crate rustbox;
extern crate rustc_serialize;

use std::default::Default;

use rustbox::{Color, RustBox};
use rustbox::Key;

use rustc_serialize::json;

use hkg::utility::cache;
use hkg::model::TopicItem;

fn main() {

    loop {
        // GUI init
        let rustbox = match RustBox::init(Default::default()) {
            Result::Ok(v) => v,
            Result::Err(e) => panic!("{}", e),
        };

        let w = rustbox.width();
        let h = rustbox.height();
        let title = String::from("高登");
        print_header(&rustbox, w, title);

        let s = cache::readfile(String::from("topics.json"));
        let collection: Vec<TopicItem> = json::decode(&s).unwrap();

        print_body(&rustbox, w, 2, h - 3, collection);

        rustbox.print(1,
                      h - 1,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      "Press 'q' to quit.");

        rustbox.present();
        match rustbox.poll_event(false) {
            Ok(rustbox::Event::KeyEvent(key)) => {
                match key {
                    Key::Char('q') => {
                        break;
                    }
                    _ => {}
                }
            }
            Err(e) => panic!("{}", e),
            _ => {}
        }
    }
}

fn print_header(rustbox: &rustbox::RustBox, width: usize, text: String) {
    let padding = (width - text.len()) / 2;
    let header_bottom = (0..width).map(|_| "─").collect::<Vec<_>>().join("");
    rustbox.print(padding,
                  0,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  &text);
    rustbox.print(0,
                  1,
                  rustbox::RB_BOLD,
                  Color::Yellow,
                  Color::Black,
                  &header_bottom);
}

fn print_body(rustbox: &rustbox::RustBox,
              width: usize,
              offset_x: usize,
              rows: usize,
              collection: Vec<TopicItem>) {

    let right_offset = 3;
    let author_max_width = 12;
    let no_max_width = 5;
    let title_max_width = width - no_max_width - author_max_width - right_offset;
    let author_position = width - author_max_width - right_offset;

    for (i, item) in collection.iter().take(rows).enumerate() {

        let title: String = item.titles[0].text.chars().take(title_max_width/2).collect();

        rustbox.print(0,
                      i + offset_x,
                      rustbox::RB_NORMAL,
                      Color::White,
                      Color::Black,
                      &format!("[{no:0>2}] {title}",
                               no = i + 1,
                               title = title));

        rustbox.print(author_position,
                      i + offset_x,
                      rustbox::RB_NORMAL,
                      Color::White,
                      Color::Black,
                      &format!("| {author}", author = &item.author.name));
    }

    rustbox.print(0,
                  rows + 2,
                  rustbox::RB_NORMAL,
                  Color::White,
                  Color::Black,
                  &format!("{} {}", title_max_width, author_position));

}

// fn debug_load_and_print_topics() {
//     let s = cache::readfile(String::from("topics.json"));
//     let collection: Vec<TopicItem> = json::decode(&s).unwrap();
//
//     println!("topics {:?}", collection.len());
//     debug_print_topics(collection);
// }
//
// fn debug_print_topics(collection: Vec<TopicItem>) {
//     for (i, item) in collection.iter().enumerate() {
//
//         println!("item[{}]= {title} {author_name} {last_replied_date} {last_replied_time} \
//                   {reply_count} {rating}",
//                  i,
//                  title = item.titles[0].text,
//                  author_name = item.author.name,
//                  last_replied_date = item.last_replied_date,
//                  last_replied_time = item.last_replied_time,
//                  reply_count = item.reply_count,
//                  rating = item.rating);
//     }
// }
<|endoftext|>


<commit_before>// Copyright (c) 2016, 2018 Nikita Pekin and the ferru contributors
// See the README.md file at the top-level directory of this distribution.
//
// 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.

//! Ferru is a lightweight, blazing fast static site generator.
//!
//! This binary serves as a frontend to the Ferru static site generation
//! functionality provided by the ferru library.

#![deny(missing_docs)]
#![deny(non_camel_case_types)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate ferru;
#[macro_use]
extern crate log;
extern crate mustache;

use clap::{App, ArgMatches};
use ferru::Config;

fn main() {
    env_logger::init()
        .expect("Failed to initialize env_logger");

    // Create the CLI.
    let yml = load_yaml!("../cli.yml");
    let matches = App::from_yaml(yml).get_matches();

    // Run the program.
    run(matches);
}

fn run(m: ArgMatches) {
    // Match the raw subcommand, and get its sub-matches "m".
    if let (name, Some(sub_m)) = m.subcommand() {
        let config = config_from_matches(sub_m);
        match name {
            "build" => ferru::build(&config).unwrap(),
            _ => unreachable!(),
        }
    }
}

fn config_from_matches<'a>(matches: &'a ArgMatches) -> Config<'a> {
    Config {
        source_directory: matches.value_of("source"),
        dest_directory: matches.value_of("dest"),
    }
}
<commit_msg>fix: correct destination arg name<commit_after>// Copyright (c) 2016, 2018 Nikita Pekin and the ferru contributors
// See the README.md file at the top-level directory of this distribution.
//
// 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.

//! Ferru is a lightweight, blazing fast static site generator.
//!
//! This binary serves as a frontend to the Ferru static site generation
//! functionality provided by the ferru library.

#![deny(missing_docs)]
#![deny(non_camel_case_types)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

#[macro_use]
extern crate clap;
extern crate env_logger;
extern crate ferru;
#[macro_use]
extern crate log;
extern crate mustache;

use clap::{App, ArgMatches};
use ferru::Config;

fn main() {
    env_logger::init()
        .expect("Failed to initialize env_logger");

    // Create the CLI.
    let yml = load_yaml!("../cli.yml");
    let matches = App::from_yaml(yml).get_matches();

    // Run the program.
    run(matches);
}

fn run(m: ArgMatches) {
    // Match the raw subcommand, and get its sub-matches "m".
    if let (name, Some(sub_m)) = m.subcommand() {
        let config = config_from_matches(sub_m);
        match name {
            "build" => ferru::build(&config).unwrap(),
            _ => unreachable!(),
        }
    }
}

fn config_from_matches<'a>(matches: &'a ArgMatches) -> Config<'a> {
    Config {
        source_directory: matches.value_of("source"),
        dest_directory: matches.value_of("destination"),
    }
}
<|endoftext|>


<commit_before>#![feature(old_io,net,core,io)]
use std::net::UdpSocket;

const NTP_SERVER: &'static str = "sundial.columbia.edu:123";
const UDP_LOCAL: &'static str = "0.0.0.0:35000";

const NTP_CLIENT: u8 = 3;

const LEAP_SHIFT: i32 = 6;
const VERSION_SHIFT: i32 = 3;

struct NTPTimestamp {
    seconds: u32,
    fraction: u32
}

struct NTPHeader {
    leap: u8,
    version: u8,
    mode: u8,
    stratum: u8,
    poll: u8,
    precision: u8,
    root_delay: u32,
    root_dispersion: u32,
    reference_id: u32,
    reference_timestamp: NTPTimestamp,
    origin_timestamp: NTPTimestamp,
    receive_timestamp: NTPTimestamp,
    transmit_timestamp: NTPTimestamp,
}

impl NTPHeader {
    pub fn new() -> NTPHeader {
        NTPHeader {
            leap: 0,
            version: 3,
            mode: NTP_CLIENT,
            stratum: 0,
            poll: 0,
            precision: 0,
            root_delay : 0,
            root_dispersion : 0,
            reference_id : 0,
            reference_timestamp : NTPTimestamp{seconds:0, fraction:0},
            origin_timestamp : NTPTimestamp{seconds:0, fraction:0},
            receive_timestamp : NTPTimestamp{seconds:0, fraction:0},
            transmit_timestamp : NTPTimestamp{seconds:0, fraction:0}
        }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut vec = Vec::<u8>::new();

        vec.write_u8(self.leap << LEAP_SHIFT | self.version << VERSION_SHIFT | self.mode).unwrap();
        vec.write_u8(self.stratum).unwrap();
        vec.write_u8(self.poll).unwrap();
        vec.write_u8(self.precision).unwrap();
        vec.write_be_u32(self.root_delay).unwrap();
        vec.write_be_u32(self.root_dispersion).unwrap();
        vec.write_be_u32(self.reference_id).unwrap();
        vec.write_be_u32(self.reference_timestamp.seconds).unwrap();
        vec.write_be_u32(self.reference_timestamp.fraction).unwrap();
        vec.write_be_u32(self.origin_timestamp.seconds).unwrap();
        vec.write_be_u32(self.origin_timestamp.fraction).unwrap();
        vec.write_be_u32(self.receive_timestamp.seconds).unwrap();
        vec.write_be_u32(self.receive_timestamp.fraction).unwrap();
        vec.write_be_u32(self.transmit_timestamp.seconds).unwrap();
        vec.write_be_u32(self.transmit_timestamp.fraction).unwrap();
        vec
    }
}

fn receive_network_timestamp() -> Result<(), std::io::Error> {
    let header = NTPHeader::new();
    let message = header.encode();

    let socket = try!(UdpSocket::bind(UDP_LOCAL));

    try!(socket.send_to(message.as_slice(), (NTP_SERVER)));

    let mut buf = [0u8; 1000];

    let (amt, src) = try!(socket.recv_from(buf.as_mut_slice()));
    println!("Got {} bytes from {}.", amt, src);

    drop(socket);

    Ok(())
}

fn main() {
    match receive_network_timestamp() {
        Ok(_) => {},
        Err(e) => panic!("Error retrieving network timestamp: {}", e),
    }
}
<commit_msg>NTP response handling<commit_after>#![feature(old_io,net,core,io)]
use std::net::UdpSocket;
use std::old_io::BufReader;

const NTP_SERVER: &'static str = "sundial.columbia.edu:123";
const UDP_LOCAL: &'static str = "0.0.0.0:35000";

const NTP_CLIENT: u8 = 3;
const NTP_HEADER_SIZE: usize = 48; // 12 words

const LEAP_SHIFT: i32 = 6;
const VERSION_SHIFT: i32 = 3;

#[derive(Clone, Debug)]
struct NTPTimestamp {
    seconds: u32,
    fraction: u32
}

#[derive(Debug)]
struct NTPHeader {
    leap: u8,
    version: u8,
    mode: u8,
    stratum: u8,
    poll: u8,
    precision: u8,
    root_delay: u32,
    root_dispersion: u32,
    reference_id: u32,
    reference_timestamp: NTPTimestamp,
    origin_timestamp: NTPTimestamp,
    receive_timestamp: NTPTimestamp,
    transmit_timestamp: NTPTimestamp,
}

impl NTPHeader {
    pub fn new() -> NTPHeader {
        NTPHeader {
            leap: 0,
            version: 3,
            mode: NTP_CLIENT,
            stratum: 0,
            poll: 0,
            precision: 0,
            root_delay : 0,
            root_dispersion : 0,
            reference_id : 0,
            reference_timestamp : NTPTimestamp{seconds:0, fraction:0},
            origin_timestamp : NTPTimestamp{seconds:0, fraction:0},
            receive_timestamp : NTPTimestamp{seconds:0, fraction:0},
            transmit_timestamp : NTPTimestamp{seconds:0, fraction:0}
        }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut vec = Vec::<u8>::new();

        vec.write_u8(self.leap << LEAP_SHIFT | self.version << VERSION_SHIFT | self.mode).unwrap();
        vec.write_u8(self.stratum).unwrap();
        vec.write_u8(self.poll).unwrap();
        vec.write_u8(self.precision).unwrap();
        vec.write_be_u32(self.root_delay).unwrap();
        vec.write_be_u32(self.root_dispersion).unwrap();
        vec.write_be_u32(self.reference_id).unwrap();
        vec.write_be_u32(self.reference_timestamp.seconds).unwrap();
        vec.write_be_u32(self.reference_timestamp.fraction).unwrap();
        vec.write_be_u32(self.origin_timestamp.seconds).unwrap();
        vec.write_be_u32(self.origin_timestamp.fraction).unwrap();
        vec.write_be_u32(self.receive_timestamp.seconds).unwrap();
        vec.write_be_u32(self.receive_timestamp.fraction).unwrap();
        vec.write_be_u32(self.transmit_timestamp.seconds).unwrap();
        vec.write_be_u32(self.transmit_timestamp.fraction).unwrap();
        vec
    }

    pub fn decode(size: usize, buf: & [u8]) -> NTPHeader {
        let mut reader = BufReader::new(buf);
        let mut header = NTPHeader::new();

        if size < NTP_HEADER_SIZE {
            panic!("{} bytes expected in NTP header; {} bytes received", NTP_HEADER_SIZE, size);
        }

        let leap_version_mode = reader.read_u8().unwrap();
        header.leap = (leap_version_mode >> LEAP_SHIFT) & 0b11;
        header.version = (leap_version_mode >> VERSION_SHIFT) & 0b111;
        header.mode = leap_version_mode & 0b111;
        header.stratum = reader.read_u8().unwrap();
        header.poll = reader.read_u8().unwrap();
        header.precision = reader.read_u8().unwrap();
        header.root_delay = reader.read_be_u32().unwrap();
        header.root_dispersion = reader.read_be_u32().unwrap();
        header.reference_id = reader.read_be_u32().unwrap();
        header.reference_timestamp.seconds = reader.read_be_u32().unwrap();
        header.reference_timestamp.fraction = reader.read_be_u32().unwrap();
        header.origin_timestamp.seconds = reader.read_be_u32().unwrap();
        header.origin_timestamp.fraction = reader.read_be_u32().unwrap();
        header.receive_timestamp.seconds = reader.read_be_u32().unwrap();
        header.receive_timestamp.fraction = reader.read_be_u32().unwrap();
        header.transmit_timestamp.seconds = reader.read_be_u32().unwrap();
        header.transmit_timestamp.fraction = reader.read_be_u32().unwrap();

        header
    }
}

fn receive_network_timestamp() -> Result<NTPTimestamp, std::io::Error> {
    let header = NTPHeader::new();
    let message = header.encode();

    let socket = try!(UdpSocket::bind(UDP_LOCAL));

    try!(socket.send_to(message.as_slice(), (NTP_SERVER)));

    let mut buf = [0u8; 1000];

    let (amt, _) = try!(socket.recv_from(buf.as_mut_slice()));

    drop(socket);

    let header = NTPHeader::decode(amt, &buf);

    Ok(header.transmit_timestamp.clone())
}

fn main() {
    let timestamp = match receive_network_timestamp() {
        Ok(s) => s,
        Err(e) => panic!("Error retrieving network timestamp: {}", e),
    };

    println!("seconds:{} fraction:{}", timestamp.seconds, timestamp.fraction);
}
<|endoftext|>


<commit_before>/*
    Copyright © 2021 Alastair Feille

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

    SPDX-License-Identifier: MPL-2.0
*/

use std::{env,
          fs,
          io,
          io::Write,
          path::PathBuf,
          process,
          process::Command};

use chrono::Local;

mod history;

fn main()
{
    let session_time = Local::now();
    let mut fallback_mode = false;
    loop
    {
        let cwd: String = env::current_dir().map(|p| {
                                                // Attempt to canonicalize the path else return "???"
                                                fs::canonicalize(p).unwrap_or("???".into())
                                                                   .to_string_lossy()
                                                                   .into()
                                            })
                                            // Attempt to get the current path else return "???"
                                            .unwrap_or("???".into());
        // Print prompt
        print!("{}{}@{}:{}> ",
               if fallback_mode { "(bash) " } else { "" },
               whoami::username(),
               whoami::hostname(),
               cwd);
        io::stdout().flush().expect("failed to print prompt");

        // Read in line
        let mut line = String::new();
        io::stdin().read_line(&mut line)
                   .expect("failed to read from stdin");

        let original_line = line.clone();
        let line = line.trim();
        // Skip empty lines
        if line.is_empty()
        {
            continue;
        }
        if line == "\u{0014}"
        {
            // toggle fallback mode
            fallback_mode = !fallback_mode;
            continue;
        }

        // Split line into command and arguments
        let tokens: Vec<&str> = line.split_whitespace().collect();
        let (head, args) = tokens.split_at(1);
        if let Some(cmd) = head.get(0)
        {
            // If the line doesn't start with a space
            if !original_line.starts_with(char::is_whitespace)
            {
                history::log(session_time,
                             Local::now(),
                             line.to_string(),
                             env::current_dir().ok(),
                             fallback_mode);
            }
            if cmd.to_string() == "exit"
            {
                process::exit(0);
            }
            if cmd.to_string() == "cd"
            {
                let path_string = args.join(" ");
                // if no directory is given
                let p = if path_string.trim().is_empty()
                {
                    // change into the home directory
                    dirs::home_dir().expect("can't get home directory")
                }
                else
                {
                    // use the given directory
                    PathBuf::from(path_string)
                };

                if let Err(e) = env::set_current_dir(&p)
                {
                    eprintln!("mush: cd: {}: {}", p.display(), e);
                }
                continue;
            }
            let (cmd, args) = if fallback_mode
            {
                (&"bash", vec!["-c", line])
            }
            else
            {
                (cmd, Vec::from(args))
            };
            match Command::new(cmd).args(args).spawn()
            {
                Ok(mut child) =>
                {
                    let _ecode = child.wait().expect("failed to wait on child");
                },
                Err(e) => eprintln!("mush: could not run command {}: {}", cmd, e),
            }
        }
    }
}
<commit_msg>feat(fallback): load bash aliases in fallback mode<commit_after>/*
    Copyright © 2021 Alastair Feille

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

    SPDX-License-Identifier: MPL-2.0
*/

use std::{env,
          fs,
          io,
          io::Write,
          path::PathBuf,
          process,
          process::Command};

use chrono::Local;

mod history;

fn main()
{
    let session_time = Local::now();
    let mut fallback_mode = false;
    loop
    {
        let cwd: String = env::current_dir().map(|p| {
                                                // Attempt to canonicalize the path else return "???"
                                                fs::canonicalize(p).unwrap_or("???".into())
                                                                   .to_string_lossy()
                                                                   .into()
                                            })
                                            // Attempt to get the current path else return "???"
                                            .unwrap_or("???".into());
        // Print prompt
        print!("{}{}@{}:{}> ",
               if fallback_mode { "(bash) " } else { "" },
               whoami::username(),
               whoami::hostname(),
               cwd);
        io::stdout().flush().expect("failed to print prompt");

        // Read in line
        let mut line = String::new();
        io::stdin().read_line(&mut line)
                   .expect("failed to read from stdin");

        let original_line = line.clone();
        let line = line.trim();
        // Skip empty lines
        if line.is_empty()
        {
            continue;
        }
        if line == "\u{0014}"
        {
            // toggle fallback mode
            fallback_mode = !fallback_mode;
            continue;
        }

        // Split line into command and arguments
        let tokens: Vec<&str> = line.split_whitespace().collect();
        let (head, args) = tokens.split_at(1);
        if let Some(cmd) = head.get(0)
        {
            // If the line doesn't start with a space
            if !original_line.starts_with(char::is_whitespace)
            {
                history::log(session_time,
                             Local::now(),
                             line.to_string(),
                             env::current_dir().ok(),
                             fallback_mode);
            }
            if cmd.to_string() == "exit"
            {
                process::exit(0);
            }
            if cmd.to_string() == "cd"
            {
                let path_string = args.join(" ");
                // if no directory is given
                let p = if path_string.trim().is_empty()
                {
                    // change into the home directory
                    dirs::home_dir().expect("can't get home directory")
                }
                else
                {
                    // use the given directory
                    PathBuf::from(path_string)
                };

                if let Err(e) = env::set_current_dir(&p)
                {
                    eprintln!("mush: cd: {}: {}", p.display(), e);
                }
                continue;
            }
            let (cmd, args) = if fallback_mode
            {
                let aliases =
                    String::from_utf8_lossy(
                                            &Command::new("bash").args(vec![
                        "-c",
                        "source ~/.bash_aliases 2> /dev/null; alias",
                    ])
                                                                 .output()
                                                                 .expect("failed to load aliases")
                                                                 .stdout,
                    ).to_string();

                (&"bash",
                 vec!["-c".to_string(),
                      format!("shopt -s expand_aliases\n{}\n{}", aliases, line)])
            }
            else
            {
                let args: Vec<String> = args.iter().map(|s| s.to_string()).collect();
                (cmd, args)
            };
            match Command::new(cmd).args(args).spawn()
            {
                Ok(mut child) =>
                {
                    let _ecode = child.wait().expect("failed to wait on child");
                },
                Err(e) => eprintln!("mush: could not run command {}: {}", cmd, e),
            }
        }
    }
}
<|endoftext|>


<commit_before>struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        self.data.slice(addr as usize, (addr + bytes) as usize)
    }

    fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

}

struct Instr<'a> {
    opcode: u8,
    data: Option<&'a [u8]>,
    cycles: usize,
}

impl<'a> Instr<'a> {

    fn parse(reg: &mut RegData, rom: &'a AddressSpace) -> Instr<'a> {
        let opcode = rom.read(reg.advance_pc());
        Instr {
            opcode: opcode,
            data: None,
            cycles: 4,
        }
    }

    fn opcode(&self) -> u8 {
        self.opcode
    }

    fn cycles(&self) -> usize {
        self.cycles
    }

    fn param(&self, i: usize) -> u8 {
        self.data.expect("Instruction type does not carry parameters")[i]
    }

}

enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    PC,
    Flag,
}

struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    pc: u16,
    flag: u8,
}

impl RegData {

    fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            pc: 0x100,
            flag: 0,
        }
    }

    fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            Register::PC => self.pc,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            Register::PC => self.pc = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    fn copy(&mut self, dst: Register, src: Register) {
        let data = self.read(src);
        self.write(dst, data);
    }

    fn copy_u16(&mut self, dst: Register, src: Register) {
        let data = self.read_u16(src);
        self.write_u16(dst, data);
    }

    fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

    fn advance_pc(&mut self) -> u16 {
        let pc = self.pc;
        self.pc += 1;
        pc
    }

}

static GB_FREQUENCY: u32 = 4194304;

struct Cpu {
    reg: RegData,
    ram: AddressSpace,
    freq: u32,
    clock: u64,
    cycle_block: u32,
}

impl Cpu {

    fn new() -> Cpu {
        Cpu::new_with_freq(GB_FREQUENCY)
    }

    fn new_with_freq(freq: u32) -> Cpu {
        Cpu {
            reg: RegData::new(),
            ram: AddressSpace::new(),
            freq: freq,
            clock: 0,
            cycle_block: 0,
        }
    }

    fn do_cycle(&mut self) {
        self.clock += 1;
        if self.cycle_block > 0 {
            self.cycle_block -= 1;
        } else {
            let instr = Instr::parse(&mut self.reg, &self.ram);
            match instr.opcode() {
                _ => panic!("Instruction not implemented!"),
            }
        }
    }

}

fn main() {
    println!("Hello, world!");
}
<commit_msg>Change type of instruction cycle count<commit_after>struct AddressSpace {
    data: [u8; 0xFFFF],
}

impl AddressSpace {

    fn new() -> AddressSpace {
        AddressSpace { data: [0; 0xFFFF] }
    }

    fn read(&self, addr: u16) -> u8 {
        self.data[addr as usize]
    }

    fn read_slice(&self, addr: u16, bytes: u16) -> &[u8] {
        self.data.slice(addr as usize, (addr + bytes) as usize)
    }

    fn write(&mut self, addr: u16, data: u8) {
        self.data[addr as usize] = data;
    }

}

struct Instr<'a> {
    opcode: u8,
    data: Option<&'a [u8]>,
    cycles: u32,
}

impl<'a> Instr<'a> {

    fn parse(reg: &mut RegData, rom: &'a AddressSpace) -> Instr<'a> {
        let opcode = rom.read(reg.advance_pc());
        Instr {
            opcode: opcode,
            data: None,
            cycles: 4,
        }
    }

    fn opcode(&self) -> u8 {
        self.opcode
    }

    fn cycles(&self) -> u32 {
        self.cycles
    }

    fn param(&self, i: usize) -> u8 {
        self.data.expect("Instruction type does not carry parameters")[i]
    }

}

enum RegFlag {
    Zero,
    Subtract,
    HalfCarry,
    Carry,
}

enum Register {
    A,
    B,
    C,
    D,
    E,
    F,
    H,
    L,
    AF,
    BC,
    DE,
    HL,
    SP,
    PC,
    Flag,
}

struct RegData {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
    e: u8,
    f: u8,
    h: u8,
    l: u8,
    sp: u16,
    pc: u16,
    flag: u8,
}

impl RegData {

    fn new() -> RegData {
        RegData {
            a: 0,
            b: 0,
            c: 0,
            d: 0,
            e: 0,
            f: 0,
            h: 0,
            l: 0,
            sp: 0xFFFE,
            pc: 0x100,
            flag: 0,
        }
    }

    fn read(&self, reg: Register) -> u8 {
        match reg {
            Register::A => self.a,
            Register::B => self.b,
            Register::C => self.c,
            Register::D => self.d,
            Register::E => self.e,
            Register::F => self.f,
            Register::H => self.h,
            Register::L => self.l,
            Register::Flag => self.flag,
            _ => panic!("Register not available for 8-bit read"),
        }
    }

    fn read_u16(&self, reg: Register) -> u16 {
        match reg {
            Register::AF => (self.a as u16) << 8 | self.f as u16,
            Register::BC => (self.b as u16) << 8 | self.c as u16,
            Register::DE => (self.d as u16) << 8 | self.e as u16,
            Register::HL => (self.h as u16) << 8 | self.l as u16,
            Register::SP => self.sp,
            Register::PC => self.pc,
            _ => panic!("Register not available for 16-bit read"),
        }
    }

    fn write(&mut self, reg: Register, data: u8) {
        match reg {
            Register::A => self.a = data,
            Register::B => self.b = data,
            Register::C => self.c = data,
            Register::D => self.d = data,
            Register::E => self.e = data,
            Register::F => self.f = data,
            Register::H => self.h = data,
            Register::L => self.l = data,
            _ => panic!("Register not available for 8-bit write"),
        }
    }

    fn write_u16(&mut self, reg: Register, data: u16) {
        let (hi, lo) = ((data & 0xFF00 >> 8) as u8, (data & 0xFF) as u8);
        match reg {
            Register::AF => {
                self.a = hi;
                self.f = lo;
            },
            Register::BC => {
                self.b = hi;
                self.c = lo;
            },
            Register::DE => {
                self.d = hi;
                self.c = lo;
            },
            Register::HL => {
                self.h = hi;
                self.l = lo;
            },
            Register::SP => self.sp = data,
            Register::PC => self.pc = data,
            _ => panic!("Register not available for 16-bit write"),
        }
    }

    fn copy(&mut self, dst: Register, src: Register) {
        let data = self.read(src);
        self.write(dst, data);
    }

    fn copy_u16(&mut self, dst: Register, src: Register) {
        let data = self.read_u16(src);
        self.write_u16(dst, data);
    }

    fn set_flag(&mut self, flag: RegFlag, on: bool) {
        let bit = match flag {
            RegFlag::Zero => 0x80,
            RegFlag::Subtract => 0x40,
            RegFlag::HalfCarry => 0x20,
            RegFlag::Carry => 0x10,
        };
        if (on) {
            self.flag |= bit;
        } else {
            self.flag &= bit ^ 0xFF;
        }
    }

    fn advance_pc(&mut self) -> u16 {
        let pc = self.pc;
        self.pc += 1;
        pc
    }

}

static GB_FREQUENCY: u32 = 4194304;

struct Cpu {
    reg: RegData,
    ram: AddressSpace,
    freq: u32,
    clock: u64,
    cycle_block: u32,
}

impl Cpu {

    fn new() -> Cpu {
        Cpu::new_with_freq(GB_FREQUENCY)
    }

    fn new_with_freq(freq: u32) -> Cpu {
        Cpu {
            reg: RegData::new(),
            ram: AddressSpace::new(),
            freq: freq,
            clock: 0,
            cycle_block: 0,
        }
    }

    fn do_cycle(&mut self) {
        self.clock += 1;
        if self.cycle_block > 0 {
            self.cycle_block -= 1;
        } else {
            let instr = Instr::parse(&mut self.reg, &self.ram);
            match instr.opcode() {
                _ => panic!("Instruction not implemented!"),
            }
        }
    }

}

fn main() {
    println!("Hello, world!");
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate colored;
extern crate xmltree;

mod utils;

use std::cmp::{Ord, Ordering};

use colored::*;
use xmltree::Element;

use crate::utils::{log_print, LogLevel};

use clap::{App, Arg};

#[derive(Debug, Eq, PartialEq, PartialOrd)]
struct Attr<'attr> {
    key: &'attr str,
    value: &'attr str,
}

impl<'attr> Attr<'attr> {
    fn new(data: (&'attr str, &'attr str)) -> Attr<'attr> {
        Attr {
            key: data.0,
            value: data.1,
        }
    }

    fn print(&self) -> String {
        format!("{}=\"{}\"", self.key, self.value)
    }
}

impl<'attr> Ord for Attr<'attr> {
    fn cmp(&self, rhs: &Attr<'attr>) -> Ordering {
        self.key.cmp(rhs.key)
    }
}

#[derive(Debug)]
struct Tag<'tag> {
    el: &'tag Element,
    attrs: Vec<Attr<'tag>>,
}

impl<'tag> PartialEq for Tag<'tag> {
    fn eq(&self, rhs: &Tag<'tag>) -> bool {
        match self.el.get_text() {
            Some(_) => self.el.get_text() == rhs.el.get_text(),
            None => self.el.name == rhs.el.name && self.attrs == rhs.attrs,
        }
    }
}

impl<'tag> Tag<'tag> {
    fn new(el: &'tag Element) -> Tag<'tag> {
        let mut ret_val: Tag<'tag> = Tag {
            el,
            attrs: Vec::new(),
        };

        for attr in &el.attributes {
            let attr: Attr<'tag> = Attr::<'tag>::new((attr.0, attr.1));
            ret_val.attrs.push(attr);
        }

        ret_val.attrs.sort();

        ret_val
    }

    fn print(&self, indent: &usize) -> String {
        let mut ret_val: String = " ".repeat(*indent);
        ret_val.push('<');

        ret_val.push_str(&self.el.name);

        for attr in &self.attrs {
            ret_val.push(' ');
            ret_val.push_str(&attr.print());
        }

        ret_val.push_str(">");

        if let Some(ref text) = self.el.get_text() {
            ret_val.push_str(text);
            ret_val.push_str(&format!("</{}>", self.el.name));
        }

        ret_val
    }

    fn print_end(&self, indent: &usize) -> Option<String> {
        if !self.has_text() {
            Some(format!("{}</{}>", " ".repeat(*indent), self.el.name))
        } else {
            None
        }
    }

    fn has_text(&self) -> bool {
        self.el.get_text().is_some()
    }

    fn print_diff(&self, indent: &usize) -> String {
        format!(
            "{}{}\n{}",
            "|".green(),
            &self.print(&if *indent > 0 { *indent - 1 } else { 0 }),
            "|".red()
        )
    }
}

fn compare_nodes<'cn>(tag_x: &Tag<'cn>, tag_y: &Tag<'cn>, indent: &'cn mut usize) {
    let start_tag = tag_x.print(indent);
    let end_tag = tag_x.print_end(indent);

    *indent += 2;

    println!("{}", start_tag);

    for child_x in &tag_x.el.children {
        let tag_child_x: Tag = Tag::new(child_x.as_element().unwrap());
        let mut found: bool = false;

        for child_y in &tag_y.el.children {
            let tag_child_y: Tag = Tag::new(child_y.as_element().unwrap());

            if tag_child_x == tag_child_y {
                found = true;

                compare_nodes(&tag_child_x, &tag_child_y, indent);

                break;
            }
        }

        if !found {
            println!("{}", tag_child_x.print_diff(indent));
        }
    }

    if let Some(v) = end_tag {
        println!("{}", v)
    }

    *indent -= 2;
}

fn main() {
    let args = App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .arg(Arg::with_name("FILE1").required(true).index(1))
        .arg(Arg::with_name("FILE2").required(true).index(2))
        .get_matches();

    let file1_path: String = value_t_or_exit!(args.value_of("FILE1"), String);
    let file2_path: String = value_t_or_exit!(args.value_of("FILE2"), String);

    let content_x: String = match utils::read_file_content(&file1_path) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let content_y: String = match utils::read_file_content(&file2_path) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let el_x: Element = match Element::parse(content_x.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(&LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let el_y: Element = match Element::parse(content_y.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(&LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let mut indent: usize = 0;
    let tag_x: Tag = Tag::new(&el_x);
    let tag_y: Tag = Tag::new(&el_y);

    if tag_x == tag_y {
        compare_nodes(&tag_x, &tag_y, &mut indent);
    } else {
        tag_x.print_diff(&indent);
    }
}
<commit_msg>use usize instead of rf usize as fn argument<commit_after>#[macro_use]
extern crate clap;
extern crate colored;
extern crate xmltree;

mod utils;

use std::cmp::{Ord, Ordering};

use colored::*;
use xmltree::Element;

use crate::utils::{log_print, LogLevel};

use clap::{App, Arg};

#[derive(Debug, Eq, PartialEq, PartialOrd)]
struct Attr<'attr> {
    key: &'attr str,
    value: &'attr str,
}

impl<'attr> Attr<'attr> {
    fn new(data: (&'attr str, &'attr str)) -> Attr<'attr> {
        Attr {
            key: data.0,
            value: data.1,
        }
    }

    fn print(&self) -> String {
        format!("{}=\"{}\"", self.key, self.value)
    }
}

impl<'attr> Ord for Attr<'attr> {
    fn cmp(&self, rhs: &Attr<'attr>) -> Ordering {
        self.key.cmp(rhs.key)
    }
}

#[derive(Debug)]
struct Tag<'tag> {
    el: &'tag Element,
    attrs: Vec<Attr<'tag>>,
}

impl<'tag> PartialEq for Tag<'tag> {
    fn eq(&self, rhs: &Tag<'tag>) -> bool {
        match self.el.get_text() {
            Some(_) => self.el.get_text() == rhs.el.get_text(),
            None => self.el.name == rhs.el.name && self.attrs == rhs.attrs,
        }
    }
}

impl<'tag> Tag<'tag> {
    fn new(el: &'tag Element) -> Tag<'tag> {
        let mut ret_val: Tag<'tag> = Tag {
            el,
            attrs: Vec::new(),
        };

        for attr in &el.attributes {
            let attr: Attr<'tag> = Attr::<'tag>::new((attr.0, attr.1));
            ret_val.attrs.push(attr);
        }

        ret_val.attrs.sort();

        ret_val
    }

    fn print(&self, indent: usize) -> String {
        let mut ret_val: String = " ".repeat(indent);
        ret_val.push('<');

        ret_val.push_str(&self.el.name);

        for attr in &self.attrs {
            ret_val.push(' ');
            ret_val.push_str(&attr.print());
        }

        ret_val.push_str(">");

        if let Some(ref text) = self.el.get_text() {
            ret_val.push_str(text);
            ret_val.push_str(&format!("</{}>", self.el.name));
        }

        ret_val
    }

    fn print_end(&self, indent: usize) -> Option<String> {
        if !self.has_text() {
            Some(format!("{}</{}>", " ".repeat(indent), self.el.name))
        } else {
            None
        }
    }

    fn has_text(&self) -> bool {
        self.el.get_text().is_some()
    }

    fn print_diff(&self, indent: usize) -> String {
        format!(
            "{}{}\n{}",
            "|".green(),
            &self.print(if indent > 0 { indent - 1 } else { 0 }),
            "|".red()
        )
    }
}

fn compare_nodes<'cn>(tag_x: &Tag<'cn>, tag_y: &Tag<'cn>, indent: &'cn mut usize) {
    let start_tag = tag_x.print(*indent);
    let end_tag = tag_x.print_end(*indent);

    *indent += 2;

    println!("{}", start_tag);

    for child_x in &tag_x.el.children {
        let tag_child_x: Tag = Tag::new(child_x.as_element().unwrap());
        let mut found: bool = false;

        for child_y in &tag_y.el.children {
            let tag_child_y: Tag = Tag::new(child_y.as_element().unwrap());

            if tag_child_x == tag_child_y {
                found = true;

                compare_nodes(&tag_child_x, &tag_child_y, indent);

                break;
            }
        }

        if !found {
            println!("{}", tag_child_x.print_diff(*indent));
        }
    }

    if let Some(v) = end_tag {
        println!("{}", v)
    }

    *indent -= 2;
}

fn main() {
    let args = App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .arg(Arg::with_name("FILE1").required(true).index(1))
        .arg(Arg::with_name("FILE2").required(true).index(2))
        .get_matches();

    let file1_path: String = value_t_or_exit!(args.value_of("FILE1"), String);
    let file2_path: String = value_t_or_exit!(args.value_of("FILE2"), String);

    let content_x: String = match utils::read_file_content(&file1_path) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let content_y: String = match utils::read_file_content(&file2_path) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let el_x: Element = match Element::parse(content_x.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(&LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let el_y: Element = match Element::parse(content_y.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(&LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let mut indent: usize = 0;
    let tag_x: Tag = Tag::new(&el_x);
    let tag_y: Tag = Tag::new(&el_y);

    if tag_x == tag_y {
        compare_nodes(&tag_x, &tag_y, &mut indent);
    } else {
        tag_x.print_diff(indent);
    }
}
<|endoftext|>


<commit_before>use std::collections::{
    HashMap,
    BinaryHeap,
};
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};

use std::hash::Hash;

use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
    IntoEdges,
    EdgeRef,
};
use algo::Measure;

/// [Generic] Dijkstra's shortest path algorithm.
///
/// Compute the length of the shortest path from `start` to every reachable
/// node.
///
/// The graph should be `Visitable` and implement `IntoEdges`. The function
/// `edge_cost` should return the cost for a particular edge, which is used
/// to compute path costs. Edge costs must be non-negative.
///
/// If `goal` is not `None`, then the algorithm terminates once the `goal` node's
/// cost is calculated.
///
/// Returns a `HashMap` that maps `NodeId` to path cost.
pub fn dijkstra<G, F, K>(graph: G, start: G::NodeId, goal: Option<G::NodeId>,
                         mut edge_cost: F)
    -> HashMap<G::NodeId, K>
    where G: IntoEdges + Visitable,
          G::NodeId: Eq + Hash,
          F: FnMut(G::EdgeRef) -> K,
          K: Measure + Copy,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    //let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score = K::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.is_visited(&node) {
            continue
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        for edge in graph.edges(node) {
            let next = edge.target();
            if visited.is_visited(&next) {
                continue
            }
            let mut next_score = node_score + edge_cost(edge);
            match scores.entry(next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    //predecessor.insert(next.clone(), node.clone());
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    //predecessor.insert(next.clone(), node.clone());
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        visited.visit(node);
    }
    scores
}
<commit_msg>Add doc for dijkstra<commit_after>use std::collections::{
    HashMap,
    BinaryHeap,
};
use std::collections::hash_map::Entry::{
    Occupied,
    Vacant,
};

use std::hash::Hash;

use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
    IntoEdges,
    EdgeRef,
};
use algo::Measure;

/// [Generic] Dijkstra's shortest path algorithm.
///
/// Compute the length of the shortest path from `start` to every reachable
/// node.
///
/// The graph should be `Visitable` and implement `IntoEdges`. The function
/// `edge_cost` should return the cost for a particular edge, which is used
/// to compute path costs. Edge costs must be non-negative.
///
/// If `goal` is not `None`, then the algorithm terminates once the `goal` node's
/// cost is calculated.
///
/// Returns a `HashMap` that maps `NodeId` to path cost.
/// # Example
/// ```rust
/// use petgraph::Graph;
/// use petgraph::algo::dijkstra;
/// use petgraph::prelude::*;
/// use std::collections::HashMap;
///
/// let mut graph : Graph<(),(),Directed>= Graph::new();
/// let a = graph.add_node(()); // node with no weight
/// let b = graph.add_node(());
/// let c = graph.add_node(());
/// let d = graph.add_node(());
/// let e = graph.add_node(());
/// let f = graph.add_node(());
/// let g = graph.add_node(());
/// let h = graph.add_node(());
/// // z will be in another connected component
/// let z = graph.add_node(());
///
/// graph.extend_with_edges(&[
///     (a, b),
///     (b, c),
///     (c, d),
///     (d, a),
///     (e, f),
///     (b, e),
///     (f, g),
///     (g, h),
///     (h, e)
/// ]);
/// // a ----> b ----> e ----> f
/// // ^       |       ^       |
/// // |       v       |       v
/// // d <---- c       h <---- g
///
/// let expected_res: HashMap<NodeIndex, usize> = [
///      (a, 3),
///      (b, 0),
///      (c, 1),
///      (d, 2),
///      (e, 1),
///      (f, 2),
///      (g, 3),
///      (h, 4)
///     ].iter().cloned().collect();
/// let res = dijkstra(&graph,b,None, |_| 1);
/// assert_eq!(res, expected_res);
/// // z is not inside res because there is not path from b to z.
/// ```
pub fn dijkstra<G, F, K>(graph: G, start: G::NodeId, goal: Option<G::NodeId>,
                         mut edge_cost: F)
    -> HashMap<G::NodeId, K>
    where G: IntoEdges + Visitable,
          G::NodeId: Eq + Hash,
          F: FnMut(G::EdgeRef) -> K,
          K: Measure + Copy,
{
    let mut visited = graph.visit_map();
    let mut scores = HashMap::new();
    //let mut predecessor = HashMap::new();
    let mut visit_next = BinaryHeap::new();
    let zero_score = K::default();
    scores.insert(start, zero_score);
    visit_next.push(MinScored(zero_score, start));
    while let Some(MinScored(node_score, node)) = visit_next.pop() {
        if visited.is_visited(&node) {
            continue
        }
        if goal.as_ref() == Some(&node) {
            break
        }
        for edge in graph.edges(node) {
            let next = edge.target();
            if visited.is_visited(&next) {
                continue
            }
            let mut next_score = node_score + edge_cost(edge);
            match scores.entry(next) {
                Occupied(ent) => if next_score < *ent.get() {
                    *ent.into_mut() = next_score;
                    //predecessor.insert(next.clone(), node.clone());
                } else {
                    next_score = *ent.get();
                },
                Vacant(ent) => {
                    ent.insert(next_score);
                    //predecessor.insert(next.clone(), node.clone());
                }
            }
            visit_next.push(MinScored(next_score, next));
        }
        visited.visit(node);
    }
    scores
}
<|endoftext|>


<commit_before>fn main() {
    let mut a = "abc";

    let n = change_a(&mut a);

    println!("n is: {}", n);
}

fn change_a<'a>(a: &'a mut &'a str) -> &'a str {

    println!("prev a is: {}", a);

    *a = "xyz";

    println!("changed a is: {}", a);

    "hh"
}<commit_msg>chore: macro_rules<commit_after>macro_rules! gen_func {

    ($func: ident) => {

        fn $func() {

            println!("current function is: {}", stringify!($func));
        }
    }

}

fn main() {

    gen_func!(abc);

    abc();
}<|endoftext|>


<commit_before>trait StringChars<T> {
    fn all_chars(self) -> Vec<T>;
}

impl StringChars<String> for String {
    fn all_chars(self) -> Vec<String> {
        let char_vec: Vec<String> = self
                                    .split("")
                                    .map(|cur_char| { cur_char.to_string() })
                                    .collect();
        char_vec
    }
}

trait VecExtensions<T> {
    fn last_pos(&self) -> usize;
}

impl VecExtensions<String> for Vec<String> {
    fn last_pos(&self) -> usize {
        self.len() - 1
    }
}

fn vec_shift(input: &Vec<String>, start: usize, end: usize) -> String {
    input
    .iter()
    .enumerate()
    .filter(|&(i, _)| { i >= start && i <= end }) // end needed for one case otherwise not
    .map(|(i, x)| { x.to_string() })
    .collect::<Vec<String>>()
    .join("")
}

fn shift_seq(offset: i32, base_seq: String) -> String {
    let mut new_seq = String::new();
    let seq_vec: Vec<String> = base_seq.all_chars();

    if offset >= seq_vec.len() as i32 {
        println!("Here's a problem!");
        new_seq = vec_shift(&seq_vec, (offset as usize) % seq_vec.len(), seq_vec.last_pos());
        if offset % seq_vec.len() as i32 != 0 {
            new_seq = format!("{}{}", new_seq, vec_shift(&seq_vec, 0, (offset as usize) % seq_vec.len() - 1))
        }
    } else {
        new_seq = vec_shift(&seq_vec, offset as usize, seq_vec.last_pos());
        if offset != 0 {
            new_seq = format!("{}{}", new_seq, vec_shift(&seq_vec, 0, (offset - 1) as usize))
        }
    }
    new_seq
}

fn main() {
    // PROBLEMS:
    // - Doesn't add Everything before starting point to the end (PROBLEM part of 3)
    //   With offset over 26 it works again
    // - Doesn't start shifting at 1, but at 2
    // - In Else part, fix the offset != 0 problem

    let shift = shift_seq(30, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_string());
    println!("{}", shift);
}
<commit_msg>Implement encipher method<commit_after>trait StringChars<T> {
    fn all_chars(self) -> Vec<T>;
}

impl StringChars<String> for String {
    fn all_chars(self) -> Vec<String> {
        let char_vec: Vec<String> = self
                                    .split("")
                                    .map(|cur_char| { cur_char.to_string() })
                                    .collect();
        char_vec
    }
}

trait VecExtensions<T> {
    fn last_pos(&self) -> usize;
}

impl VecExtensions<String> for Vec<String> {
    fn last_pos(&self) -> usize {
        self.len() - 1
    }
}

fn vec_shift(input: &Vec<String>, start: usize, end: usize) -> String {
    input
    .iter()
    .enumerate()
    .filter(|&(i, _)| { i >= start && i <= end }) // end needed for one case otherwise not
    .map(|(i, x)| { x.to_string() })
    .collect::<Vec<String>>()
    .join("")
}

fn shift_seq(offset: i32, base_seq: String) -> String {
    let mut new_seq = String::new();
    let seq_vec: Vec<String> = base_seq.all_chars();

    if offset >= seq_vec.len() as i32 {
        new_seq = vec_shift(&seq_vec, (offset as usize) % seq_vec.len(), seq_vec.last_pos());
        if offset % seq_vec.len() as i32 != 0 {
            new_seq = format!("{}{}", new_seq, vec_shift(&seq_vec, 0, (offset as usize) % seq_vec.len() - 1));
        }
    } else {
        new_seq = vec_shift(&seq_vec, offset as usize, seq_vec.last_pos());
        if offset != 0 {
            new_seq = format!("{}{}", new_seq, vec_shift(&seq_vec, 0, (offset - 1) as usize));
        }
    }
    new_seq
}

fn encipher(offset: i32, message: &str) -> String {
    let base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    let base_seq = base.to_string().all_chars();
    let new_seq = shift_seq(offset, base.to_string()).all_chars();

    let mut new_string = String::new();

    for achar in message.to_string().all_chars() {
        let mut found = false;
        for i in 0..base_seq.last_pos() {
            if achar == base_seq[i] {
                new_string += &new_seq[i];
                found = true;
            }
        }
        if !found {
            new_string += "achar"
        }
    }

    new_string
}

fn main() {
    // PROBLEMS:
    // - Doesn't add Everything before starting point to the end (PROBLEM part of 3)
    //   With offset over 26 it works again
    // - Doesn't start shifting at 1, but at 2
    // - In Else part, fix the offset != 0 problem

    let shift = shift_seq(30, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_string());
    let shiftString = encipher(2, "Konnichiwa");
    println!("{}", shiftString);
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate termios;

use libc::{STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, winsize};
use termios::{Termios, tcsetattr, TCSAFLUSH, VMIN, VTIME};
use termios::{BRKINT, ICRNL, INPCK, ISTRIP, IXON};
use termios::{OPOST, CS8};
use termios::{ECHO, ICANON, IEXTEN, ISIG};

use std::io::{self, Stdin, Stdout, Read, Error, ErrorKind, Write};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

macro_rules! ctrl_key {
    ($k:expr) => ($k & 0x1f);
}

struct TermReset {
    orig_term: Termios
}

struct EditorConfig {
    _term: TermReset,
    screenrows: u16,
    screencols: u16,
}

struct Editor {
    config: EditorConfig,
    stdin: Stdin,
    stdout: Stdout,
}

impl Drop for TermReset {
    fn drop(&mut self) {
        tcsetattr(STDIN_FILENO, TCSAFLUSH, &self.orig_term).unwrap()
    }
}

fn enable_raw_mode() -> io::Result<TermReset> {
    let mut term = Termios::from_fd(STDIN_FILENO)?;
    let mode = TermReset { orig_term: term.clone() };

    term.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    term.c_oflag &= !OPOST;
    term.c_cflag |= CS8;
    term.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
    term.c_cc[VMIN] = 0;
    term.c_cc[VTIME] = 1;

    tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)?;
    Ok(mode)
}

impl EditorConfig {
    fn new() -> EditorConfig {
        let term = enable_raw_mode().unwrap();
        let (rows, cols) = get_window_size().unwrap();
        EditorConfig { _term: term, screenrows: rows, screencols: cols }
    }
}

impl Editor {
    fn new(config: EditorConfig) -> Editor {
        let stdin = io::stdin();
        let stdout = io::stdout();
        Editor { config: config, stdin: stdin, stdout: stdout }
    }
}

impl Drop for Editor {
    fn drop(&mut self) {
        self.stdout.write(b"\x1b[2J").unwrap();
        self.stdout.write(b"\x1b[H").unwrap();
        self.stdout.flush().unwrap();
    }
}

fn editor_read_key(stdin: &mut Stdin) -> u8 {
    let mut buf = [0; 1];
    loop {
        let n = stdin.read(&mut buf)
                 .or_else(|e| if e.kind() == ErrorKind::WouldBlock { Ok(0) } else { Err(e) })
                 .expect("read");
        if n == 1 {
            return buf[0];
        }
    }
}

fn get_window_size() -> io::Result<(u16, u16)> {
    let ws = winsize { ws_col: 0, ws_row: 0, ws_xpixel: 0, ws_ypixel: 0 };
    unsafe {
        if libc::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0 {
            return Err(Error::new(ErrorKind::Other, "get_window_size: ioctl failed"))
        }
    }
    Ok((ws.ws_row, ws.ws_col))
}

fn editor_draw_rows(stdout: &mut Stdout, e: &EditorConfig) -> io::Result<()> {
    for y in 0..(e.screenrows) {
        if y == e.screenrows / 3 {
            let mut msg = format!("Kilo-rs editor -- version {}", VERSION);
            msg.truncate(e.screencols as usize);
            let padding = (e.screencols - msg.len() as u16) / 2;
            if padding > 0 {
                stdout.write(b"~")?;
                for _ in 1..padding {
                    stdout.write(b" ")?;
                }
            }
            stdout.write(msg.as_bytes())?;
        } else {
            stdout.write(b"~")?;
        }

        stdout.write(b"\x1b[K")?;
        if y < e.screenrows - 1 {
            stdout.write(b"\r\n")?;
        }
    }
    Ok(())
}

fn editor_refresh_screen(stdout: &mut Stdout, e: &EditorConfig) -> io::Result<()> {
    stdout.write(b"\x1b[?25l")?;
    stdout.write(b"\x1b[H")?;

    editor_draw_rows(stdout, e)?;

    stdout.write(b"\x1b[H")?;
    stdout.write(b"\x1b[?25h")?;
    stdout.flush()
}

fn editor_process_keypress(stdin: &mut Stdin) -> bool {
    let c = editor_read_key(stdin);

    match c {
        k if k == ctrl_key!(b'q') => {
            false
        },
        _ => true
    }
}

fn main() {
    let mut editor = Editor::new(EditorConfig::new());

    editor_refresh_screen(&mut editor.stdout, &editor.config).unwrap();
    while editor_process_keypress(&mut editor.stdin) {
        editor_refresh_screen(&mut editor.stdout, &editor.config).unwrap();
    }
}
<commit_msg>Refactorings: rename TermReset -> RawMode, merge structs EditorConfig and Editor, move editor methods to editor struct<commit_after>extern crate libc;
extern crate termios;

use libc::{STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, winsize};
use termios::{Termios, tcsetattr, TCSAFLUSH, VMIN, VTIME};
use termios::{BRKINT, ICRNL, INPCK, ISTRIP, IXON};
use termios::{OPOST, CS8};
use termios::{ECHO, ICANON, IEXTEN, ISIG};

use std::io::{self, Stdin, Stdout, Read, Error, ErrorKind, Write};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

macro_rules! ctrl_key {
    ($k:expr) => ($k & 0x1f);
}

struct RawMode {
    orig_term: Termios
}

struct Editor {
    _mode: RawMode,
    screenrows: u16,
    screencols: u16,
    stdin: Stdin,
    stdout: Stdout,
}

impl RawMode {
    fn enable_raw_mode() -> io::Result<RawMode> {
        let mut term = Termios::from_fd(STDIN_FILENO)?;
        let mode = RawMode { orig_term: term.clone() };

        term.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        term.c_oflag &= !OPOST;
        term.c_cflag |= CS8;
        term.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
        term.c_cc[VMIN] = 0;
        term.c_cc[VTIME] = 1;

        tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)?;
        Ok(mode)
    }
}

impl Drop for RawMode {
    fn drop(&mut self) {
        tcsetattr(STDIN_FILENO, TCSAFLUSH, &self.orig_term).unwrap()
    }
}

fn editor_read_key(stdin: &mut Stdin) -> u8 {
    let mut buf = [0; 1];
    loop {
        let n = stdin.read(&mut buf)
                 .or_else(|e| if e.kind() == ErrorKind::WouldBlock { Ok(0) } else { Err(e) })
                 .expect("read");
        if n == 1 {
            return buf[0];
        }
    }
}

fn get_window_size() -> io::Result<(u16, u16)> {
    let ws = winsize { ws_col: 0, ws_row: 0, ws_xpixel: 0, ws_ypixel: 0 };
    unsafe {
        if libc::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0 {
            return Err(Error::new(ErrorKind::Other, "get_window_size: ioctl failed"))
        }
    }
    Ok((ws.ws_row, ws.ws_col))
}

impl Editor {
    fn new() -> io::Result<Editor> {
        let mode = RawMode::enable_raw_mode()?;
        let (rows, cols) = get_window_size()?;
        let stdin = io::stdin();
        let stdout = io::stdout();
        Ok(Editor { _mode: mode, screenrows: rows, screencols: cols, stdin: stdin, stdout: stdout })
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.stdout.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.stdout.flush()
    }

    fn draw_rows(&mut self) -> io::Result<()> {
        for y in 0..(self.screenrows) {
            if y == self.screenrows / 3 {
                let mut msg = format!("Kilo-rs editor -- version {}", VERSION);
                msg.truncate(self.screencols as usize);
                let padding = (self.screencols - msg.len() as u16) / 2;
                if padding > 0 {
                    self.write(b"~")?;
                    for _ in 1..padding {
                        self.write(b" ")?;
                    }
                }
                self.write(msg.as_bytes())?;
            } else {
                self.write(b"~")?;
            }

            self.write(b"\x1b[K")?;
            if y < self.screenrows - 1 {
                self.write(b"\r\n")?;
            }
        }
        Ok(())
    }

    fn refresh_screen(&mut self) -> io::Result<()> {
        self.write(b"\x1b[?25l")?;
        self.write(b"\x1b[H")?;

        self.draw_rows()?;

        self.write(b"\x1b[H")?;
        self.write(b"\x1b[?25h")?;
        self.flush()
    }

    fn process_keypress(&mut self) -> bool {
        let c = editor_read_key(&mut self.stdin);

        match c {
            k if k == ctrl_key!(b'q') => {
                false
            },
            _ => true
        }
    }
}

impl Drop for Editor {
    fn drop(&mut self) {
        // clear screen
        self.stdout.write(b"\x1b[2J").unwrap();
        self.stdout.write(b"\x1b[H").unwrap();
        self.stdout.flush().unwrap();
    }
}

fn main() {
    let mut editor = Editor::new().unwrap();

    editor.refresh_screen().unwrap();
    while editor.process_keypress() {
        editor.refresh_screen().unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate clap;

mod error;

use clap::{App, Arg, ArgMatches, AppSettings, SubCommand};
use error::{Error, Result};
use std::env;
use std::fs;
use std::path;

fn init_empty_blog(m: &ArgMatches) -> Result<()> {
    let dir = path::Path::new(m.value_of("dir").unwrap_or("."));

    let file = fs::OpenOptions::new()
        .write(true)
        .create(true)
        .truncate(true)
        .open(dir.join(".config"))
        .map_err(|e| format!("failed to create `.config`: {}", e))?;

    let file = fs::OpenOptions::new()
        .write(true)
        .create(true)
        .truncate(true)
        .open(dir.join(".nojekyll"))
        .map_err(|e| format!("failed to create `.nojekyll`: {}", e))?;
    fs::create_dir(dir.join("files"))
        .map_err(|e| format!("failed to create `files`: {}", e))?;

    Ok(())
}

fn main() {
    let app = App::new(env::args().nth(0).unwrap())
        .settings(&[AppSettings::DisableVersion,
                    AppSettings::DeriveDisplayOrder,
                    AppSettings::UnifiedHelpMessage,
                    AppSettings::VersionlessSubcommands])
        .subcommand(SubCommand::with_name("init")
                    .about("Initialize an empty blog")
                    .args(&[
                        Arg::from_usage("[dir] 'Directory for the blog'"),
                    ]))
        .subcommand(SubCommand::with_name("gen")
                    .about("Generate the blog"))
        .subcommand(SubCommand::with_name("view")
                    .about("View the blog locally"))
        .get_matches();

    let ret = match app.subcommand() {
        ("init", Some(m)) => init_empty_blog(m),
        ("gen", Some(m)) => Ok(()),
        ("view", Some(m)) => Ok(()),
        _ => Ok(())
    };

    if let Err(e) = ret {
        println!("{}", e)
    }
}
<commit_msg>Add --force flag to init command<commit_after>extern crate clap;

mod error;

use clap::{App, Arg, ArgMatches, AppSettings, SubCommand};
use error::{Error, Result};
use std::env;
use std::fs;
use std::path;

fn init_empty_site(m: &ArgMatches) -> Result<()> {
    let dir = path::Path::new(m.value_of("dir").unwrap_or("."));

    let opt = match m.is_present("force") {
        true  => fs::OpenOptions::new()
                 .write(true).create(true).truncate(true).clone(),
        false => fs::OpenOptions::new()
                 .write(true).create_new(true).clone(),
    };

    opt.open(dir.join(".config"))
       .map_err(|e| format!("failed to create `.config`: {}", e))?;
    opt.open(dir.join(".nojekyll"))
       .map_err(|e| format!("failed to create `.nojekyll`: {}", e))?;

    fs::DirBuilder::new()
        .recursive(m.is_present("force"))
        .create(dir.join("files"))
        .map_err(|e| format!("failed to create `files`: {}", e))?;

    Ok(())
}

fn main() {
    let app = App::new(env::args().nth(0).unwrap())
        .settings(&[AppSettings::DisableVersion,
                    AppSettings::DeriveDisplayOrder,
                    AppSettings::UnifiedHelpMessage,
                    AppSettings::VersionlessSubcommands])
        .subcommand(SubCommand::with_name("init")
                    .about("Initialize an empty site")
                    .args(&[
                        Arg::from_usage("[dir] 'Directory for the site'"),
                        Arg::from_usage("-f, --force 'Overwrite existing \
                                        site metadata files'"),
                    ]))
        .subcommand(SubCommand::with_name("gen")
                    .about("Generate the site"))
        .subcommand(SubCommand::with_name("view")
                    .about("View the site locally"))
        .get_matches();

    let ret = match app.subcommand() {
        ("init", Some(m)) => init_empty_site(m),
        ("gen", Some(m)) => Ok(()),
        ("view", Some(m)) => Ok(()),
        _ => Ok(())
    };

    if let Err(e) = ret {
        println!("{}", e)
    }
}
<|endoftext|>


<commit_before>fn main() {
    let logfile_path = match std::os::homedir() {
        Some(ref p) => p.join(".eyl-shell.log"),
        None        => fail!("finding homedir")
    };
    let mut logfile = std::io::File::create(&logfile_path);
    match logfile.write(b"It works!\n") {
        Ok(()) => (),
        Err(_) => fail!("writing to logfile")
    }
}
<commit_msg>Started adding raw Wayland interface<commit_after>mod raw {
    extern crate libc;

    #[allow(non_camel_case_types)]
    pub type wl_display = libc::c_void;

    #[link(name = "wayland-client")]
    extern {
        pub fn wl_display_connect(name: *const u8) -> *mut wl_display;
        pub fn wl_display_disconnect(display: *mut wl_display);
    }
}

pub struct Display {
    ptr: *mut raw::wl_display
}

impl Display {
    pub fn new() -> Display {
        unsafe {
            let ptr = raw::wl_display_connect(std::ptr::null());
            assert!(!ptr.is_null());
            Display { ptr: ptr }
        }
    }
}

impl Drop for Display {
    fn drop(&mut self) {
        unsafe {
            raw::wl_display_disconnect(self.ptr);
        }
    }
}

fn main() {
    let logfile_path = match std::os::homedir() {
        Some(ref p) => p.join(".eyl-shell.log"),
        None        => fail!("finding homedir")
    };
    let mut logfile = std::io::File::create(&logfile_path);
    let display = Display::new();
    match logfile.write(b"Connected to display\n") {
        Ok(()) => (),
        Err(_) => fail!("writing to logfile")
    }
}
<|endoftext|>


<commit_before>extern crate regex;

use regex::Regex;

use std::cell::Ref;
use std::cell::RefCell;

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;

use std::{thread, time};

struct Attack
{
    damage: u64,
    victim: String,
    timestamp: String,
    crit: String // "" for did not crit?
}

impl Attack
{
    fn attack(&mut self, attack_data: &regex::Captures)
    {
    }
}

struct Attacker
{
    attacks: RefCell<Vec<Attack>>,
    final_damage: u64,
    final_healed: u64,
    name: String
}

impl Attacker
{
    fn attack(&mut self, attack_data: &regex::Captures)
    {
        self.final_damage = 50;
    }
}

struct Encounter
{
    attackers: Vec<Attacker>,
    encounter_start: String, //timestamp of when the fight started, get this from whatever starts the encounter
    encounter_duration: u64 //duration of the encounter in nanoseconds, divide by 1000 to get seconds
}

impl Encounter
{
    fn exists(&self, name:&str) -> bool
    {
        /*for i in 0..((self.attackers.botemp-1rrow()).len())
        {
            if ((self.attackers).borrow())[i].name == name
            {
                return  true;
            }
        }
        return false;*/
        for i in 0..((self.attackers).len())
        {
            if ((self.attackers))[i].name == name
            {
                return  true;
            }
        }
        return false;
    }

    fn attack(&mut self, attack_data: regex::Captures)
    {
        if !self.exists(attack_data.name("attacker").unwrap())
        {
            (self.attackers).push(Attacker{attacks: RefCell::new(Vec::new()), final_damage: 0, final_healed: 0, name: String::from(attack_data.name("attacker").unwrap())});
            let attackers_len = self.attackers.len() - 1;
            (self.attackers)[attackers_len].attack(&attack_data);
        }
        println!("{}",attack_data.name("attack").unwrap());
        self.encounter_start = String::from("Test");
    }
}

fn main()
{
    let f = File::open("/home/bergman/Documents/rust/EXP/eq2log_Shepherd.txt").unwrap();
    /*{
        Ok(file) => file,
        Err(e) =>
        {
            println!("{}", e);
        }
    };*/

    //Start a encounter, this code will be moved into the main loop when it works
    let mut encounters: Vec<Encounter> = Vec::new();
    encounters.push(Encounter{ attackers: Vec::new(), encounter_start: String::from("START"), encounter_duration : 0});

    let re = Regex::new(r"\((?P<time>\d+)\)\[(?P<datetime>(\D|\d)+)\] (?P<attacker>\D+)(YOUR|'s) (?P<attack>\D+) ((multi attacks)|multi) (?P<target>\D+) for a (?P<crittype>\D+) of (?P<damage>\d+) (cold|heat|mental|arcane|poison|noxious) damage").unwrap();

    let mut file = BufReader::new(&f);

    let mut buffer = String::new();
    let mut battle_timer = time::Instant::now();
    'main: loop
    {
        if file.read_line(&mut buffer).unwrap() > 0
        {
            /*CHECK IF ATTACK
                CHECK ATTACKER, IF NO ATTACKER EXISTS CREATE A NEW ONE <-- this is done by String-matching the ATTACKERS name
                    PARSE ATTACK INTO ENCOUNTERS.ATTACKERS.ATTACK <-- this is done by String-matching the ATTACKERS name
            SAME FOR HEAL*/
            let temp = re.captures(buffer.as_str()) ;
            match temp {None => {}, Some(cap) =>
            {
                //look to see if the attacker already has a post, if so place the attack there, if not push a new attacker
                encounters[0].attack(cap);
                //encounters[0].attackers.cap.name("datetime").unwrap()
            }};
            //if buffer.find("attacks") != ;
            encounters[0].encounter_duration += battle_timer.elapsed().subsec_nanos() as u64;
            battle_timer = time::Instant::now();
        }
        else
        {
            thread::sleep(time::Duration::from_millis(100));
            if battle_timer.elapsed() >= time::Duration::from_millis(3000)
            {
                println!("New battle incoming, {:?} time has elapsed since the last one.", battle_timer.elapsed().as_secs());
            }
        }
        buffer.clear();
    }
}

/*
(1477272172)[Mon Oct 24 03:22:52 2016] YOUR Raging Whirlwind multi attacks Bonesnapper for a critical of 38996 cold damage.\r\n
(1477272172)[Mon Oct 24 03:22:52 2016] Kabernet\'s Asylum multi attacks Bonesnapper for a critical of 36622 mental damage.\r\n

DATASTRUCTURE:
I should probably parse attacks into vectors as well, as there are a limited number of attacks viable and I am likely to want to be able to output all of a specific attack or the total damage of one particular attack
    This is advanced though so I won't do it for the first iteration of the program.

what I should be able to do:

* printout a full encounter as player dps, sorted by dps.
** This should be calculated by final damage divided by encounter_time in seconds

* printout a full encounter as player hps, sorted by hps
** This should be calculated by final healed divided by encounter_time in seconds

*/
<commit_msg>Finished merge and modified the regex slightly.<commit_after>extern crate regex;

use regex::Regex;

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;
use std::io::SeekFrom;

use std::fmt;

use std::{thread, time};

struct Attack
{
    damage: u64,
    victim: String,
    timestamp: String,
    crit: String // "" for did not crit?
}

impl Attack
{
    fn attack(&mut self, attack_data: &regex::Captures)
    {
    }
}

struct Attacker
{
    attacks: Vec<Attack>,
    final_damage: u64,
    final_healed: u64,
    name: String
}

impl Attacker
{
    fn attack(&mut self, attack_data: &regex::Captures)
    {
        self.attacks.push(Attack{damage: attack_data.name("damage").unwrap().parse::<u64>().unwrap(), victim: String::from(attack_data.name("target").unwrap()), timestamp: String::from(attack_data.name("datetime").unwrap()), crit: String::from(attack_data.name("crittype").unwrap())});
        self.final_damage += attack_data.name("damage").unwrap().parse::<u64>().unwrap();
        println!("{}-{}-damage", self.name, self.final_damage);
    }

    fn print(&self) -> &str
    {"Test"}
}

struct Encounter
{
    attackers: Vec<Attacker>,
    encounter_start: String, //timestamp of when the fight started, get this from whatever starts the encounter
    encounter_duration: u64 //duration of the encounter in nanoseconds, divide by 1000 to get seconds
}

impl Encounter
{
    fn exists(&self, name:&str) -> bool
    {
        for i in 0..((self.attackers).len())
        {
            if ((self.attackers))[i].name == name
            {
                return  true;
            }
        }
        return false;
    }

    fn attack(&mut self, attack_data: regex::Captures)
    {
        if !self.exists(attack_data.name("attacker").unwrap())
        {
            (self.attackers).push(Attacker{attacks: Vec::new(), final_damage: 0, final_healed: 0, name: String::from(attack_data.name("attacker").unwrap())});
        }
        {
            let attackers_len = self.attackers.len() - 1;
            (self.attackers)[attackers_len].attack(&attack_data);
        }
        self.encounter_start = String::from(attack_data.name("datetime").unwrap());
    }
}

impl fmt::Display for Encounter
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        write!(f, "Encounter:\n");
        for i in 0..((self.attackers).len())
        {
            write!(f, "{}", ((self.attackers))[i].print());
        }
        write!(f, "\nFight over")
    }
}

fn main()
{
    let f = File::open("/home/bergman/Documents/rust/EXP/eq2log_Shepherd.txt").unwrap();
    /*{
        Ok(file) => file,
        Err(e) =>
        {
            println!("{}", e);
        }
    };*/

    //Start a encounter, this code will be moved into the main loop when it works
    let mut encounters: Vec<Encounter> = Vec::new();
    encounters.push(Encounter{ attackers: Vec::new(), encounter_start: String::from("START"), encounter_duration : 0});

    let re = Regex::new(r"\((?P<time>\d+)\)\[(?P<datetime>(\D|\d)+)\] (?P<attacker>\D*?)(' |'s |YOUR )(?P<attack>\D+) ((multi attacks)|hits|hit) (?P<target>\D+) (?P<crittype>\D+) (?P<damage>\d+) (?P<damagetype>[A-Za-z]+) damage").unwrap();

    let mut file = BufReader::new(&f);
    file.seek(SeekFrom::End(-10));

    let mut buffer = String::new();
    let mut battle_timer = time::Instant::now();
    let mut fightdone = true;
    'main: loop
    {
        buffer.clear();
        if file.read_line(&mut buffer).unwrap() > 0
        {
            match re.captures(buffer.as_str()) {None => {}, Some(cap) =>
            {
                if fightdone
                {
                    println!("New fight!");
                    encounters.push(Encounter{ attackers: Vec::new(), encounter_start: String::from("START"), encounter_duration : 0});
                    fightdone = false;
                }
                encounters.last_mut().unwrap().attack(cap);
                battle_timer = time::Instant::now();
                encounters.last_mut().unwrap().encounter_duration += battle_timer.elapsed().subsec_nanos() as u64;
            }};
        }
        else
        {
            thread::sleep(time::Duration::from_millis(100));
        }
        if battle_timer.elapsed() >= time::Duration::from_millis(3000)
        {
            if !fightdone
            {
                println!("{}", encounters.last().unwrap());
                fightdone = true;
            }
        }
    }
}

/*
(1477272172)[Mon Oct 24 03:22:52 2016] YOUR Raging Whirlwind multi attacks Bonesnapper for a critical of 38996 cold damage.\r\n
(1477272172)[Mon Oct 24 03:22:52 2016] Kabernet\'s Asylum multi attacks Bonesnapper for a critical of 36622 mental damage.\r\n

DATASTRUCTURE:
I should probably parse attacks into vectors as well, as there are a limited number of attacks viable and I am likely to want to be able to output all of a specific attack or the total damage of one particular attack
    This is advanced though so I won't do it for the first iteration of the program.

what I should be able to do:

* printout a full encounter as player dps, sorted by dps.
** This should be calculated by final damage divided by encounter_time in seconds

* printout a full encounter as player hps, sorted by hps
** This should be calculated by final healed divided by encounter_time in seconds

*/
<|endoftext|>