<commit_before>#![feature(libc, fs_ext, path_ext, convert, fs, exit_status)]
#![allow(dead_code)]

extern crate crypto;
extern crate libc;

#[macro_use]
extern crate log;
extern crate env_logger;

use crypto::sha2::Sha512;
use crypto::digest::Digest;
use libc::{getgid, getuid};
use std::env;
use std::path::Path;
use std::os::unix::fs::PermissionsExt;
use std::io;
use std::io::{Read, Write};
use std::fs::{File, Permissions, create_dir_all,
              set_permissions, PathExt};
use std::process::{Command, Stdio};

const ALL_PERMISSIONS: usize = 0777;
const OTHER_EXECUTE: usize = 0001;
const OTHER_READ: usize = 0004;
const OTHER_RWX: usize = 0007;
const GROUP_EXECUTE: usize = 0010;
const GROUP_READ: usize = 0040;
const GROUP_RWX: usize = 0070;
const USER_EXECUTE: usize = 0100;
const USER_READ: usize = 0400;
const USER_RWX: usize = 0700;

trait PermExt2 {
    fn contains(&self, mask: usize) -> bool;
}

impl PermExt2 for Permissions {
    fn contains(&self, mask: usize) -> bool {
        self.mode() & (mask as i32) != 0
    }
}

const CACHE_SUBPATH: &'static str = "pexe-runner-cache";
// TODO: support overriding cache location.
const CACHE_BASE: &'static str = "/tmp";

const RUST_PNACL_TRANS: &'static str = "rust_pnacl_trans";

fn mkdir<P: AsRef<Path>>(p: P, mode: usize) -> io::Result<()> {
    try!(create_dir_all(&p));
    chmod(p, mode)
}
fn chmod<P: AsRef<Path>>(p: P, mode: usize) -> io::Result<()> {
    let p = p.as_ref();
    let md = try!(p.metadata());
    let mut perms = md.permissions();
    perms.set_mode(mode as i32);
    set_permissions(p, perms)
}

pub fn main() {
    env_logger::init().unwrap();

    let args: Vec<String> = env::args()
        .collect();
    let pexe_path = Path::new(&(args[1])[..]);

    let cache = Path::new(CACHE_BASE).join(CACHE_SUBPATH);
    if !cache.exists() {
        mkdir(&cache, ALL_PERMISSIONS).unwrap();
    }

    // if the binary is rx by the world, don't use a user prefix when caching.

    let pexe = File::open(&pexe_path);
    if pexe.is_err() {
        panic!("could not open Pexe file!");
    }
    let mut pexe = pexe.unwrap();

    let pexe_filename = Path::new(pexe_path.file_name().unwrap());

    let pexe_stat = pexe.metadata().unwrap();
    let (cache_dir, perms) = if pexe_stat.permissions().contains(OTHER_EXECUTE | OTHER_READ) {
        let c = cache.join("other");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        (c, ALL_PERMISSIONS)
    } else if pexe_stat.permissions().contains(GROUP_EXECUTE | GROUP_READ) {
        let c = cache.join("group");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        let gid = unsafe { getgid() };
        let c = c.join(format!("{}", gid));
        if !c.exists() {
            mkdir(&c, GROUP_RWX | USER_RWX).unwrap();
        }
        (c, GROUP_RWX | USER_RWX)
    } else if pexe_stat.permissions().contains(USER_EXECUTE) {
        let c = cache.join("user");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        let uid = unsafe { getuid() };
        let c = c.join(format!("{}", uid));
        if !c.exists() {
            mkdir(&c, USER_RWX).unwrap();
        }
        (c, USER_RWX)
    } else {
        panic!("cann't execute: permissing denied");
    };
    let mut pexe_bin = Vec::new();
    pexe.read_to_end(&mut pexe_bin)
        .unwrap();

    let mut hasher = Sha512::new();
    hasher.input(pexe_bin.as_slice());
    let cache_dir = cache_dir.join(hasher.result_str());
    if !cache_dir.exists() {
        mkdir(&cache_dir, perms).unwrap();
    }
    let nexe_path = cache_dir
        .join(pexe_filename.with_extension("nexe"));

    let nacl_sdk_root = env!("NACL_SDK_ROOT");

    if !nexe_path.exists() {
        let mut cmd = Command::new(RUST_PNACL_TRANS);
        cmd.arg("--cross-path");
        cmd.arg(nacl_sdk_root);
        cmd.arg(pexe_path.display().to_string());
        cmd.arg("-o");
        cmd.arg(nexe_path.display().to_string());
        cmd.arg("--opt-level=2");
        debug!("trans cmd line: `{:?}`", cmd);
        let trans = cmd.spawn().unwrap();

        let output = trans.wait_with_output().unwrap();
        let status = output.status;
        match status {
            _ if status.success() => {
                chmod(&nexe_path, perms).unwrap();
            }
            _ => {
                let mut stderr = ::std::io::stderr();
                let mut stdout = ::std::io::stdout();
                (writeln!(&mut stderr, "`{:?}` failed:", cmd)).unwrap();
                stdout.write(output.stdout.as_slice()).unwrap();
                stderr.write(output.stderr.as_slice()).unwrap();
                env::set_exit_status(status.code().unwrap_or(1));
                return;
            }
        }
    }

    let nacl_sdk_root = Path::new(nacl_sdk_root);
    let tools = nacl_sdk_root.join("tools");
    let nacl_helper_bootstrap = tools.join("nacl_helper_bootstrap_x86_64");
    let sel_ldr_bin = tools.join("sel_ldr_x86_64");
    let irt_core = tools.join("irt_core_x86_64.nexe");

    let mut sel_ldr_args = vec!(sel_ldr_bin.display().to_string(),
                                "--r_debug=0xXXXXXXXXXXXXXXXX".to_string(),
                                "--reserved_at_zero=0xXXXXXXXXXXXXXXXX".to_string(),
                                //"-a".to_string(),
                                "-B".to_string(),
                                irt_core.display().to_string(),
                                "-l".to_string(), "/dev/null".to_string());
    sel_ldr_args.push("--".to_string());
    sel_ldr_args.push(nexe_path.display().to_string());
    for arg in &args[2..] {
        sel_ldr_args.push(arg.clone());
    }

    let mut cmd = Command::new(nacl_helper_bootstrap);
    cmd.args(sel_ldr_args.as_slice());
    cmd.stdout(Stdio::inherit());
    cmd.stderr(Stdio::inherit());
    debug!("sel_ldr cmd line: `{:?}`", cmd);
    match cmd.spawn() {
        Ok(mut process) => {
            match process.wait() {
                Ok(status) => {
                    env::set_exit_status(status.code().unwrap_or(1));
                },
                Err(e) => {
                    panic!("couldn't wait on sel_ldr: {}", e);
                }
            }
        }
        Err(e) => {
            panic!("couldn't spawn sel_ldr: {}", e);
        }
    }
}
<commit_msg>Use correct octal masks.<commit_after>#![feature(libc, fs_ext, path_ext, convert, fs, exit_status)]
#![allow(dead_code)]

extern crate crypto;
extern crate libc;

#[macro_use]
extern crate log;
extern crate env_logger;

use crypto::sha2::Sha512;
use crypto::digest::Digest;
use libc::{getgid, getuid};
use std::env;
use std::path::Path;
use std::os::unix::fs::PermissionsExt;
use std::io;
use std::io::{Read, Write};
use std::fs::{File, Permissions, create_dir_all,
              set_permissions, PathExt};
use std::process::{Command, Stdio};

const ALL_PERMISSIONS: usize = 0o0777;
const OTHER_EXECUTE: usize = 0o0001;
const OTHER_READ: usize = 0o0004;
const OTHER_RWX: usize = 0o0007;
const GROUP_EXECUTE: usize = 0o0010;
const GROUP_READ: usize = 0o0040;
const GROUP_RWX: usize = 0o0070;
const USER_EXECUTE: usize = 0o0100;
const USER_READ: usize = 0o0400;
const USER_RWX: usize = 0o0700;

trait PermExt2 {
    fn contains(&self, mask: usize) -> bool;
}

impl PermExt2 for Permissions {
    fn contains(&self, mask: usize) -> bool {
        self.mode() & (mask as i32) != 0
    }
}

const CACHE_SUBPATH: &'static str = "pexe-runner-cache";
// TODO: support overriding cache location.
const CACHE_BASE: &'static str = "/tmp";

const RUST_PNACL_TRANS: &'static str = "rust_pnacl_trans";

fn mkdir<P: AsRef<Path>>(p: P, mode: usize) -> io::Result<()> {
    try!(create_dir_all(&p));
    chmod(p, mode)
}
fn chmod<P: AsRef<Path>>(p: P, mode: usize) -> io::Result<()> {
    let p = p.as_ref();
    let md = try!(p.metadata());
    let mut perms = md.permissions();
    perms.set_mode(mode as i32);
    set_permissions(p, perms)
}

pub fn main() {
    env_logger::init().unwrap();

    let args: Vec<String> = env::args()
        .collect();
    let pexe_path = Path::new(&(args[1])[..]);

    let cache = Path::new(CACHE_BASE).join(CACHE_SUBPATH);
    if !cache.exists() {
        mkdir(&cache, ALL_PERMISSIONS).unwrap();
    }

    // if the binary is rx by the world, don't use a user prefix when caching.

    let pexe = File::open(&pexe_path);
    if pexe.is_err() {
        panic!("could not open Pexe file!");
    }
    let mut pexe = pexe.unwrap();

    let pexe_filename = Path::new(pexe_path.file_name().unwrap());

    let pexe_stat = pexe.metadata().unwrap();
    let (cache_dir, perms) = if pexe_stat.permissions().contains(OTHER_EXECUTE | OTHER_READ) {
        let c = cache.join("other");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        (c, ALL_PERMISSIONS)
    } else if pexe_stat.permissions().contains(GROUP_EXECUTE | GROUP_READ) {
        let c = cache.join("group");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        let gid = unsafe { getgid() };
        let c = c.join(format!("{}", gid));
        if !c.exists() {
            mkdir(&c, GROUP_RWX | USER_RWX).unwrap();
        }
        (c, GROUP_RWX | USER_RWX)
    } else if pexe_stat.permissions().contains(USER_EXECUTE) {
        let c = cache.join("user");
        if !c.exists() {
            mkdir(&c, ALL_PERMISSIONS).unwrap();
        }
        let uid = unsafe { getuid() };
        let c = c.join(format!("{}", uid));
        if !c.exists() {
            mkdir(&c, USER_RWX).unwrap();
        }
        (c, USER_RWX)
    } else {
        panic!("cann't execute: permissing denied");
    };
    let mut pexe_bin = Vec::new();
    pexe.read_to_end(&mut pexe_bin)
        .unwrap();

    let mut hasher = Sha512::new();
    hasher.input(pexe_bin.as_slice());
    let cache_dir = cache_dir.join(hasher.result_str());
    if !cache_dir.exists() {
        mkdir(&cache_dir, perms).unwrap();
    }
    let nexe_path = cache_dir
        .join(pexe_filename.with_extension("nexe"));

    let nacl_sdk_root = env!("NACL_SDK_ROOT");

    if !nexe_path.exists() {
        let mut cmd = Command::new(RUST_PNACL_TRANS);
        cmd.arg("--cross-path");
        cmd.arg(nacl_sdk_root);
        cmd.arg(pexe_path.display().to_string());
        cmd.arg("-o");
        cmd.arg(nexe_path.display().to_string());
        cmd.arg("--opt-level=2");
        debug!("trans cmd line: `{:?}`", cmd);
        let trans = cmd.spawn().unwrap();

        let output = trans.wait_with_output().unwrap();
        let status = output.status;
        match status {
            _ if status.success() => {
                chmod(&nexe_path, perms).unwrap();
            }
            _ => {
                let mut stderr = ::std::io::stderr();
                let mut stdout = ::std::io::stdout();
                (writeln!(&mut stderr, "`{:?}` failed:", cmd)).unwrap();
                stdout.write(output.stdout.as_slice()).unwrap();
                stderr.write(output.stderr.as_slice()).unwrap();
                env::set_exit_status(status.code().unwrap_or(1));
                return;
            }
        }
    }

    let nacl_sdk_root = Path::new(nacl_sdk_root);
    let tools = nacl_sdk_root.join("tools");
    let nacl_helper_bootstrap = tools.join("nacl_helper_bootstrap_x86_64");
    let sel_ldr_bin = tools.join("sel_ldr_x86_64");
    let irt_core = tools.join("irt_core_x86_64.nexe");

    let mut sel_ldr_args = vec!(sel_ldr_bin.display().to_string(),
                                "--r_debug=0xXXXXXXXXXXXXXXXX".to_string(),
                                "--reserved_at_zero=0xXXXXXXXXXXXXXXXX".to_string(),
                                //"-a".to_string(),
                                "-B".to_string(),
                                irt_core.display().to_string(),
                                "-l".to_string(), "/dev/null".to_string());
    sel_ldr_args.push("--".to_string());
    sel_ldr_args.push(nexe_path.display().to_string());
    for arg in &args[2..] {
        sel_ldr_args.push(arg.clone());
    }

    let mut cmd = Command::new(nacl_helper_bootstrap);
    cmd.args(sel_ldr_args.as_slice());
    cmd.stdout(Stdio::inherit());
    cmd.stderr(Stdio::inherit());
    debug!("sel_ldr cmd line: `{:?}`", cmd);
    match cmd.spawn() {
        Ok(mut process) => {
            match process.wait() {
                Ok(status) => {
                    env::set_exit_status(status.code().unwrap_or(1));
                },
                Err(e) => {
                    panic!("couldn't wait on sel_ldr: {}", e);
                }
            }
        }
        Err(e) => {
            panic!("couldn't spawn sel_ldr: {}", e);
        }
    }
}
<|endoftext|>


<commit_before>use glium;
use glutin;
use std;

use scene;

#[repr(C)]
#[derive(Clone, Copy)]
pub struct RGB {
  pub r: f32,
  pub g: f32,
  pub b: f32,
}

unsafe impl Send for RGB {}

unsafe impl glium::texture::PixelValue for RGB {
  fn get_format() -> glium::texture::ClientFormat {
    glium::texture::ClientFormat::F32F32F32
  }
}

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 600;

pub fn main() {
  use glium::DisplayBuild;

  let window =
    glutin::WindowBuilder::new()
    .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT)
    .build_glium()
    .unwrap();

  let mut image_data = vec!();
  for y in 0 .. WINDOW_HEIGHT {
    let mut row = vec!();
    for x in 0 .. WINDOW_WIDTH {
      row.push(
        RGB {
          r: x as f32 / WINDOW_WIDTH as f32,
          g: y as f32 / WINDOW_HEIGHT as f32,
          b: 0.0,
        }
      );
    }
    image_data.push(row);
  }

  let scene =
    scene::T {
      objects       :
        vec!(
          scene::Object { center: [-1.0,  0.0,  -4.0], radius: 1.0,  color: [1.0, 0.0, 0.0], emittance: 0.0 },
          scene::Object { center: [ 20.0, 10.0, 20.0], radius: 10.0, color: [1.0, 1.0, 1.0], emittance: 1.0 },
        ),
      fovy          : std::f32::consts::FRAC_PI_2,
      eye           : [0.0, 0.0,  0.0],
      look          : [0.0, 0.0, -1.0],
      up            : [0.0, 1.0,  0.0],
      ambient_light : [0.01; 3],
    };

  let mut rendered_2d = vec!();
  {
    let w = 2 * WINDOW_WIDTH;
    let h = 2 * WINDOW_HEIGHT;
    let rendered = scene.render(w, h);
    for y in 0 .. h as usize {
      let mut row = vec!();
      for x in 0 .. w as usize {
        row.push(rendered[y * w as usize + x]);
      }
      rendered_2d.push(row);
    }
  }

  let opengl_texture = glium::texture::Texture2d::new(&window, rendered_2d).unwrap();

  // building the vertex buffer, which contains all the vertices that we will draw
  let vertex_buffer = {
    #[derive(Copy, Clone)]
    struct Vertex {
      position: [f32; 2],
      tex_coords: [f32; 2],
    }

    implement_vertex!(Vertex, position, tex_coords);

    glium::VertexBuffer::new(&window,
      &[
        Vertex { position: [-1.0, -1.0], tex_coords: [0.0, 0.0] },
        Vertex { position: [-1.0,  1.0], tex_coords: [0.0, 1.0] },
        Vertex { position: [ 1.0,  1.0], tex_coords: [1.0, 1.0] },
        Vertex { position: [ 1.0, -1.0], tex_coords: [1.0, 0.0] }
      ]
    ).unwrap()
  };

  // building the index buffer
  let index_buffer =
    glium::IndexBuffer::new(
      &window,
      glium::index::PrimitiveType::TriangleStrip,
      &[1 as u16, 2, 0, 3],
    ).unwrap();

  // compiling shaders and linking them together
  let program = program!(&window,
    330 => {
      vertex: "
        #version 330

        uniform mat4 matrix;

        in vec2 position;
        in vec2 tex_coords;

        out vec2 v_tex_coords;

        void main() {
          gl_Position = matrix * vec4(position, 0.0, 1.0);
          v_tex_coords = tex_coords;
        }
      ",

      fragment: "
        #version 330
        uniform sampler2D tex;
        in vec2 v_tex_coords;
        out vec4 f_color;

        void main() {
          f_color = texture(tex, v_tex_coords);
        }
      "
    },
  ).unwrap();

  loop {
    use glium::Surface;

    // building the uniforms
    let uniforms = uniform! {
      matrix: [
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0f32]
      ],
      tex: &opengl_texture
    };

    let mut target = window.draw();
    target.clear_color(0.0, 0.0, 0.0, 0.0);
    target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
    target.finish().unwrap();

    for event in window.poll_events() {
      if let glutin::Event::Closed = event {
        return
      }
    }
  }
}
<commit_msg>minor changes<commit_after>use glium;
use glutin;
use std;

use scene;

#[repr(C)]
#[derive(Clone, Copy)]
pub struct RGB {
  pub r: f32,
  pub g: f32,
  pub b: f32,
}

unsafe impl Send for RGB {}

unsafe impl glium::texture::PixelValue for RGB {
  fn get_format() -> glium::texture::ClientFormat {
    glium::texture::ClientFormat::F32F32F32
  }
}

pub const WINDOW_WIDTH: u32 = 800;
pub const WINDOW_HEIGHT: u32 = 600;

pub fn main() {
  use glium::DisplayBuild;

  let window =
    glutin::WindowBuilder::new()
    .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT)
    .build_glium()
    .unwrap();

  let mut image_data = vec!();
  for y in 0 .. WINDOW_HEIGHT {
    let mut row = vec!();
    for x in 0 .. WINDOW_WIDTH {
      row.push(
        RGB {
          r: x as f32 / WINDOW_WIDTH as f32,
          g: y as f32 / WINDOW_HEIGHT as f32,
          b: 0.0,
        }
      );
    }
    image_data.push(row);
  }

  let scene =
    scene::T {
      objects       :
        vec!(
          scene::Object { center: [-1.0,  0.0,  -4.0], radius: 1.0,  color: [1.0, 0.0, 0.0], emittance: 0.0 },
          scene::Object { center: [ 20.0, 10.0, 20.0], radius: 10.0, color: [1.0, 1.0, 1.0], emittance: 1.0 },
        ),
      fovy          : std::f32::consts::FRAC_PI_2,
      eye           : [0.0, 0.0,  0.0],
      look          : [0.0, 0.0, -1.0],
      up            : [0.0, 1.0,  0.0],
      ambient_light : [0.01; 3],
    };

  let mut rendered_2d = vec!();
  {
    let w = 2 * WINDOW_WIDTH;
    let h = 2 * WINDOW_HEIGHT;
    let rendered = scene.render(w, h);
    for y in 0 .. h as usize {
      let mut row = vec!();
      for x in 0 .. w as usize {
        row.push(rendered[y * w as usize + x]);
      }
      rendered_2d.push(row);
    }
  }

  let texture = glium::texture::Texture2d::new(&window, rendered_2d).unwrap();

  // building the vertex buffer, which contains all the vertices that we will draw
  let vertex_buffer = {
    #[derive(Copy, Clone)]
    struct Vertex {
      position: [f32; 2],
      tex_coords: [f32; 2],
    }

    implement_vertex!(Vertex, position, tex_coords);

    glium::VertexBuffer::new(&window,
      &[
        Vertex { position: [-1.0, -1.0], tex_coords: [0.0, 0.0] },
        Vertex { position: [-1.0,  1.0], tex_coords: [0.0, 1.0] },
        Vertex { position: [ 1.0,  1.0], tex_coords: [1.0, 1.0] },
        Vertex { position: [ 1.0, -1.0], tex_coords: [1.0, 0.0] }
      ]
    ).unwrap()
  };

  // building the index buffer
  let index_buffer =
    glium::IndexBuffer::new(
      &window,
      glium::index::PrimitiveType::TriangleStrip,
      &[1 as u16, 2, 0, 3],
    ).unwrap();

  // compiling shaders and linking them together
  let program = program!(&window,
    330 => {
      vertex: "
        #version 330

        uniform mat4 matrix;

        in vec2 position;
        in vec2 tex_coords;

        out vec2 v_tex_coords;

        void main() {
          gl_Position = matrix * vec4(position, 0.0, 1.0);
          v_tex_coords = tex_coords;
        }
      ",

      fragment: "
        #version 330
        uniform sampler2D tex;
        in vec2 v_tex_coords;
        out vec4 f_color;

        void main() {
          f_color = texture(tex, v_tex_coords);
        }
      "
    },
  ).unwrap();

  loop {
    use glium::Surface;

    // building the uniforms
    let uniforms = uniform! {
      matrix: [
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0f32]
      ],
      tex: &texture,
    };

    let mut target = window.draw();
    target.clear_color(0.0, 0.0, 0.0, 0.0);
    target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
    target.finish().unwrap();

    for event in window.poll_events() {
      if let glutin::Event::Closed = event {
        return
      }
    }
  }
}
<|endoftext|>


<commit_before>extern crate hkg;

extern crate rustbox;

use std::default::Default;

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

fn main() {

    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, h, title);
    print_body(&rustbox, w, h, 2, 2);
    rustbox.print(1,
                  23,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  "Press 'q' to quit.");

    // print_cjk_count(&rustbox);
    //
    // let s2 = String::from("<<100%成功率>>如何成為成功?香港Youtuber");
    //
    // rustbox.print(1,
    //               3,
    //               rustbox::RB_BOLD,
    //               Color::White,
    //               Color::Black,
    //               &format!("{}", real_count(s2)));

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

fn contains(c: char) -> bool {
    let cjks = vec![(0x4E00..0xA000),
                    (0x3400..0x4DC0),
                    (0x20000..0x2A6E0),
                    (0x2A700..0x2B740),
                    (0x2B740..0x2B820),
                    (0xF900..0xFB00),
                    (0x2F800..0x2FA20),
                    (0x9FA6..0x9FCC)];

    for cjk in cjks {
        let h = c as u32;
        if cjk.start <= h && h < cjk.end {
            return true;
        }
    }
    return false;
}

fn real_count(s: &str) -> usize {
    return s.chars()
            .map(|x| if contains(x) {
                2
            } else {
                1
            })
            .collect::<Vec<usize>>()
            .iter()
            .fold(0, |acc, &x| acc + x);
}

fn print_header(rustbox: &rustbox::RustBox, width: usize, height: usize, text: String) {
    let padding = (width - text.len()) / 2;
    let header_bottom = (0..width).map(|i| "─").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,
              height: usize,
              offset_x: usize,
              rows: usize) {
    let titles = vec!["紅魔英超睇敢帥　十分之高招",
                      "發覺好多後生仔女搭火車地鐵 有位都唔坐"];
    let authors = vec!["電超", "程詠樂"];

    let mut title_spacing = 0;
    for i in (0..rows) {

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

        rustbox.print(60,
                      i + offset_x,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      &format!("| {author}", author = &authors[i]));
    }
}

fn print_cjk_count(rustbox: &rustbox::RustBox) {

    let mut offset_y = 2;

    let s1 = String::from("紅魔英超睇敢帥　十分之高招");
    for (b, c) in s1.chars().enumerate() {
        rustbox.print(1,
                      b + 2,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      &format!("{} 0x{:X}", c, c as u32));
    }

    offset_y = 16;

    let s2 = String::from("<<100%成功率>>如何成為成功?香港Youtuber");
    let mut s2count = 0;
    for (d, c) in s2.chars().enumerate() {
        if contains(c) {
            rustbox.print(1,
                          d + offset_y,
                          rustbox::RB_BOLD,
                          Color::White,
                          Color::Black,
                          &format!("[{:<2}] {:>2} 0x{:X} {}", d + offset_y, c, c as u32, &"YES"));
            s2count = s2count + 2;
        } else {
            rustbox.print(1,
                          d + offset_y,
                          rustbox::RB_BOLD,
                          Color::White,
                          Color::Black,
                          &format!("[{:<2}] {:>2} 0x{:X} {}", d + offset_y, c, c as u32, &"NO"));
            s2count = s2count + 1;
        }
    }

    let sum = s2.chars()
                .map(|x| if contains(x) {
                    2
                } else {
                    1
                })
                .collect::<Vec<u32>>()
                .iter()
                .fold(0, |acc, &x| acc + x);

    rustbox.print(1,
                  45,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  &format!("{} {}", sum, s2count));

}
<commit_msg>1. read topics file 2. parse topics to object 3. print topics<commit_after>extern crate hkg;

extern crate rustbox;

use std::default::Default;

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

use std::io::prelude::*;
use std::fs::File;
use hkg::utility::cache;

extern crate rustc_serialize;
use rustc_serialize::json;

#[derive(RustcDecodable)]
pub struct TopicTitleItem {
    url: String,
    text: String,
}

#[derive(RustcDecodable)]
pub struct TopicAuthorItem {
    url: String,
    name: String,
}

#[derive(RustcDecodable)]
pub struct TopicItem {
    titles: Vec<TopicTitleItem>,
    author: TopicAuthorItem,
    last_replied_date: String,
    last_replied_time: String,
    reply_count: String,
    rating: String,
}

fn main() {

    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, h, title);
    print_body(&rustbox, w, h, 2, 2);
    rustbox.print(1,
                  23,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  "Press 'q' to quit.");

    // print_cjk_count(&rustbox);
    //
    // let s2 = String::from("<<100%成功率>>如何成為成功?香港Youtuber");
    //
    // rustbox.print(1,
    //               3,
    //               rustbox::RB_BOLD,
    //               Color::White,
    //               Color::Black,
    //               &format!("{}", real_count(s2)));

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

fn contains(c: char) -> bool {
    let cjks = vec![(0x4E00..0xA000),
                    (0x3400..0x4DC0),
                    (0x20000..0x2A6E0),
                    (0x2A700..0x2B740),
                    (0x2B740..0x2B820),
                    (0xF900..0xFB00),
                    (0x2F800..0x2FA20),
                    (0x9FA6..0x9FCC)];

    for cjk in cjks {
        let h = c as u32;
        if cjk.start <= h && h < cjk.end {
            return true;
        }
    }
    return false;
}

fn real_count(s: &str) -> usize {
    return s.chars()
            .map(|x| if contains(x) {
                2
            } else {
                1
            })
            .collect::<Vec<usize>>()
            .iter()
            .fold(0, |acc, &x| acc + x);
}

fn print_header(rustbox: &rustbox::RustBox, width: usize, height: usize, text: String) {
    let padding = (width - text.len()) / 2;
    let header_bottom = (0..width).map(|i| "─").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,
              height: usize,
              offset_x: usize,
              rows: usize) {
    let titles = vec!["紅魔英超睇敢帥　十分之高招",
                      "發覺好多後生仔女搭火車地鐵 有位都唔坐"];
    let authors = vec!["電超", "程詠樂"];

    let mut title_spacing = 0;
    for i in (0..rows) {

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

        rustbox.print(60,
                      i + offset_x,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      &format!("| {author}", author = &authors[i]));
    }
}

fn print_cjk_count(rustbox: &rustbox::RustBox) {

    let mut offset_y = 2;

    let s1 = String::from("紅魔英超睇敢帥　十分之高招");
    for (b, c) in s1.chars().enumerate() {
        rustbox.print(1,
                      b + 2,
                      rustbox::RB_BOLD,
                      Color::White,
                      Color::Black,
                      &format!("{} 0x{:X}", c, c as u32));
    }

    offset_y = 16;

    let s2 = String::from("<<100%成功率>>如何成為成功?香港Youtuber");
    let mut s2count = 0;
    for (d, c) in s2.chars().enumerate() {
        if contains(c) {
            rustbox.print(1,
                          d + offset_y,
                          rustbox::RB_BOLD,
                          Color::White,
                          Color::Black,
                          &format!("[{:<2}] {:>2} 0x{:X} {}", d + offset_y, c, c as u32, &"YES"));
            s2count = s2count + 2;
        } else {
            rustbox.print(1,
                          d + offset_y,
                          rustbox::RB_BOLD,
                          Color::White,
                          Color::Black,
                          &format!("[{:<2}] {:>2} 0x{:X} {}", d + offset_y, c, c as u32, &"NO"));
            s2count = s2count + 1;
        }
    }

    let sum = s2.chars()
                .map(|x| if contains(x) {
                    2
                } else {
                    1
                })
                .collect::<Vec<u32>>()
                .iter()
                .fold(0, |acc, &x| acc + x);

    rustbox.print(1,
                  45,
                  rustbox::RB_BOLD,
                  Color::White,
                  Color::Black,
                  &format!("{} {}", sum, s2count));

}

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>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(box_syntax)]
#![feature(link_args)]

#[macro_use]
extern crate log;

#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate libc;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate cocoa;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate objc_foundation;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
#[macro_use]
extern crate objc;

#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate glutin;
#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate winit;
#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate tinyfiledialogs;

extern crate gleam;
extern crate open;

mod app;
mod window;
mod view;
mod servo;
mod platform;
mod state;

use app::{App, AppEvent, AppCommand};
use window::{Window, WindowEvent, WindowCommand};
use view::ViewEvent;
use servo::ServoEvent;
use std::cell::RefCell;
use std::rc::Rc;
use std::env::args;
use servo::{Servo, ServoUrl, WebRenderDebugOption};

fn main() {

    let logs = platform::Logger::init();

    info!("starting");

    let app = App::new().unwrap();
    let window = app.create_window().unwrap();

    let view = Rc::new(window.create_view().unwrap());

    Servo::configure(App::get_resources_path().unwrap());

    let servo = {
        let geometry = view.get_geometry();
        let waker = window.create_event_loop_waker();
        Servo::new(geometry, view.clone(), waker)
    };

    let home_url = App::get_resources_path().unwrap().parent().unwrap().join("shell_resources").join("home.html");
    let home_url = ServoUrl::from_file_path(&home_url).unwrap().into_string();

    // Skip first argument (executable), and find the first
    // argument that doesn't start with `-`
    let url = args().skip(1).find(|arg| {
        !arg.starts_with("-")
    }).unwrap_or(home_url);

    let browser = servo.create_browser(&url);
    servo.select_browser(browser.id);

    let mut state = App::get_init_state();
    state.current_window_index = Some(0);
    state.windows.push(Window::get_init_state());
    state.windows[0].current_browser_index = Some(0);
    state.windows[0].browsers.push(browser);
    app.render(&state);
    // FIXME: no mut!
    window.render(&mut state.windows[0]);

    info!("Servo version: {}", servo.version());

    // Use a RefCell, otherwise the handle_events callback needs to be a FnMut, making things a bit hard
    // FIXME: do not use a RefCell
    let state = RefCell::new(state);

    let handle_events = || {

        let mut state = state.borrow_mut();

        // Loop until no events are available anymore.
        loop {

            let app_events = app.get_events();
            let win_events = window.get_events();
            let view_events = view.get_events();
            let servo_events = servo.get_events();

            if app_events.is_empty() &&
               win_events.is_empty() &&
               view_events.is_empty() &&
               servo_events.is_empty() {
                   break
            }

            // FIXME: it's really annoying we need this
            let mut force_sync = false;
            let mut ui_invalidated = false;

            for event in app_events {
                match event {
                    AppEvent::DidFinishLaunching => {
                        // FIXME: does this work?
                    }
                    AppEvent::WillTerminate => {
                        // FIXME: does this work?
                    }
                    AppEvent::DidChangeScreenParameters => {
                        // FIXME: does this work?
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    AppEvent::DoCommand(cmd) => {
                        match cmd {
                            AppCommand::ClearHistory => {
                                // FIXME
                            }
                            AppCommand::ToggleOptionDarkTheme => {
                                state.dark_theme = !state.dark_theme;
                                ui_invalidated = true;
                            }
                        }
                    }
                }
            }

            for event in win_events {
                match event {
                    WindowEvent::EventLoopAwaken => {
                        force_sync = true;
                    }
                    WindowEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    WindowEvent::DidEnterFullScreen => {
                        // FIXME
                    }
                    WindowEvent::DidExitFullScreen => {
                        // FIXME
                    }
                    WindowEvent::WillClose => {
                        // FIXME
                    }
                    WindowEvent::OptionsClosed => {
                        state.windows[0].options_open = false;
                    }
                    WindowEvent::UrlbarFocusChanged(focused) => {
                        state.windows[0].urlbar_focused = focused;
                    }
                    WindowEvent::DoCommand(cmd) => {
                        let idx = state.windows[0].current_browser_index.unwrap();
                        let bid = state.windows[0].browsers[idx].id;
                        match cmd {
                            WindowCommand::Stop => {
                                // FIXME
                            }
                            WindowCommand::Reload => {
                                servo.reload(bid);
                            }
                            WindowCommand::NavigateBack => {
                                servo.go_back(bid);
                            }
                            WindowCommand::NavigateForward => {
                                servo.go_forward(bid);
                            }
                            WindowCommand::OpenLocation => {
                                state.windows[0].urlbar_focused = true;
                                ui_invalidated = true;
                            }
                            WindowCommand::OpenInDefaultBrowser => {
                                if let Some(ref url) = state.windows[0].browsers[idx].url {
                                    open::that(url.clone()).ok();
                                }
                            }
                            WindowCommand::ZoomIn => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom *= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomOut => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom /= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomToActualSize => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom = 1.0;
                                servo.reset_zoom();
                            }

                            WindowCommand::ToggleSidebar => {
                                state.windows[0].sidebar_is_open = !state.windows[0].sidebar_is_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::ShowOptions => {
                                state.windows[0].options_open = !state.windows[0].options_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::Load(request) => {
                                state.windows[0].browsers[idx].user_input = Some(request.clone());
                                state.windows[0].urlbar_focused = false;
                                let url = ServoUrl::parse(&request).or_else(|error| {
                                    // FIXME: weak
                                    if request.ends_with(".com") || request.ends_with(".org") || request.ends_with(".net") {
                                        ServoUrl::parse(&format!("http://{}", request))
                                    } else {
                                        Err(error)
                                    }
                                }).or_else(|_| {
                                    ServoUrl::parse(&format!("https://duckduckgo.com/html/?q={}", request))
                                });
                                match url {
                                    Ok(url) => {
                                        servo.load_url(bid, url)
                                    },
                                    Err(err) => warn!("Can't parse url: {}", err),
                                }
                            }
                            WindowCommand::ToggleOptionShowLogs => {
                                state.windows[0].logs_visible = !state.windows[0].logs_visible;
                                ui_invalidated = true;
                            },
                            WindowCommand::NewTab => {
                                let browser = servo.create_browser("about:blank");
                                servo.select_browser(browser.id);
                                servo.update_geometry(view.get_geometry());
                                state.windows[0].current_browser_index = Some(idx + 1);
                                state.windows[0].browsers.push(browser);
                                state.windows[0].urlbar_focused = true;
                                ui_invalidated = true;
                            },
                            WindowCommand::CloseTab => {
                                if state.windows[0].browsers.len() > 1 {
                                    let id = state.windows[0].browsers[idx].id;
                                    let new_id = if idx == state.windows[0].browsers.len() - 1 {
                                        state.windows[0].current_browser_index = Some(idx - 1);
                                        state.windows[0].browsers[idx - 1].id
                                    } else {
                                        state.windows[0].browsers[idx + 1].id
                                    };
                                    servo.select_browser(new_id);
                                    servo.close_browser(id);
                                    state.windows[0].browsers.remove(idx);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::PrevTab => {
                                let new_idx = if idx == 0 {
                                    state.windows[0].browsers.len() - 1
                                } else {
                                    idx - 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::NextTab => {
                                let new_idx = if idx == state.windows[0].browsers.len() - 1 {
                                    0
                                } else {
                                    idx + 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::SelectTab(idx) => {
                                if state.windows[0].current_browser_index != Some(idx) {
                                    state.windows[0].current_browser_index = Some(idx);
                                    let id = state.windows[0].browsers[idx].id;
                                    servo.select_browser(id);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::ToggleOptionFragmentBorders => { },
                            WindowCommand::ToggleOptionParallelDisplayListBuidling => { },
                            WindowCommand::ToggleOptionShowParallelLayout => { },
                            WindowCommand::ToggleOptionConvertMouseToTouch => { },
                            WindowCommand::ToggleOptionTileBorders => { },

                            WindowCommand::ToggleOptionWRProfiler => {
                                state.windows[0].debug_options.wr_profiler = !state.windows[0].debug_options.wr_profiler;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::Profiler);
                            },

                            WindowCommand::ToggleOptionWRTextureCacheDebug => {
                                state.windows[0].debug_options.wr_texture_cache_debug = !state.windows[0].debug_options.wr_texture_cache_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::TextureCacheDebug);
                            },

                            WindowCommand::ToggleOptionWRTargetDebug => {
                                state.windows[0].debug_options.wr_render_target_debug = !state.windows[0].debug_options.wr_render_target_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::RenderTargetDebug);
                            },
                        }
                    }
                }
            }

            for event in view_events {
                let idx = state.windows[0].current_browser_index.unwrap();
                let state = &mut state.windows[0].browsers[idx];
                match event {
                    ViewEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    ViewEvent::MouseWheel(delta, phase) => {
                        let (mut x, mut y) = match delta {
                            view::MouseScrollDelta::PixelDelta(x, y) => (x, y),
                            _ => (0.0, 0.0),
                        };
                        if y.abs() >= x.abs() { x = 0.0; } else { y = 0.0; }
                        servo.perform_scroll(0, 0, x, y, phase);
                    }
                    ViewEvent::MouseMoved(x, y) => {
                        state.last_mouse_point = (x, y);
                        servo.perform_mouse_move(x, y);
                    }
                    ViewEvent::MouseInput(element_state, button) => {
                        let (x, y) = state.last_mouse_point;
                        let (org_x, org_y) = state.last_mouse_down_point;
                        let last_mouse_down_button = state.last_mouse_down_button;
                        servo.perform_click(x, y, org_x, org_y, element_state, button, last_mouse_down_button);
                        state.last_mouse_down_point = (x, y);
                        if element_state == view::ElementState::Pressed {
                            state.last_mouse_down_button = Some(button);
                        }
                    }
                    ViewEvent::KeyEvent(c, key, keystate, modifiers) => {
                        servo.send_key(state.id, c, key, keystate, modifiers);
                    }
                }
            }

            for event in servo_events {
                match event {
                    ServoEvent::SetWindowInnerSize(..) => {
                        // ignore
                    }
                    ServoEvent::SetWindowPosition(..) => {
                        // ignore
                    }
                    ServoEvent::SetFullScreenState(fullscreen) => {
                        if fullscreen {
                            view.enter_fullscreen();
                        } else {
                            view.exit_fullscreen();
                        }
                    }
                    ServoEvent::TitleChanged(id, title) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.title = title;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::StatusChanged(status) => {
                        state.windows[0].status = status;
                        ui_invalidated = true;
                    }
                    ServoEvent::LoadStart(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = true;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::LoadEnd(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = false;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::HeadParsed(..) => {
                        // FIXME
                    }
                    ServoEvent::HistoryChanged(id, entries, current) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                let url = entries[current].url.to_string();
                                browser.url = Some(url);
                                browser.can_go_back = current > 0;
                                browser.can_go_forward = current < entries.len() - 1;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::CursorChanged(cursor) => {
                        state.cursor = cursor;
                        ui_invalidated = true;
                    }
                    ServoEvent::FaviconChanged(..) => {
                        // FIXME
                    }
                    ServoEvent::Key(..) => {
                        // FIXME
                    }
                    ServoEvent::OpenInDefaultBrowser(url) => {
                        open::that(url).ok();
                    }
                }
            }

            if ui_invalidated {
                app.render(&state);
                window.render(&state.windows[0]);
            }

            servo.sync(force_sync);
        }

        // Here, only stuff that we know for sure won't trigger any
        // new events

        // FIXME: logs will grow until pulled
        if state.windows[0].logs_visible {
            window.append_logs(&logs.get_logs());
        }
    };

    view.set_live_resize_callback(&handle_events);

    app.run(handle_events);

}
<commit_msg>only focus urlbar on new tab for cocoa port<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(box_syntax)]
#![feature(link_args)]

#[macro_use]
extern crate log;

#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate libc;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate cocoa;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
extern crate objc_foundation;
#[cfg(all(not(feature = "force-glutin"), target_os = "macos"))]
#[macro_use]
extern crate objc;

#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate glutin;
#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate winit;
#[cfg(any(feature = "force-glutin", not(target_os = "macos")))]
extern crate tinyfiledialogs;

extern crate gleam;
extern crate open;

mod app;
mod window;
mod view;
mod servo;
mod platform;
mod state;

use app::{App, AppEvent, AppCommand};
use window::{Window, WindowEvent, WindowCommand};
use view::ViewEvent;
use servo::ServoEvent;
use std::cell::RefCell;
use std::rc::Rc;
use std::env::args;
use servo::{Servo, ServoUrl, WebRenderDebugOption};

fn main() {

    let logs = platform::Logger::init();

    info!("starting");

    let app = App::new().unwrap();
    let window = app.create_window().unwrap();

    let view = Rc::new(window.create_view().unwrap());

    Servo::configure(App::get_resources_path().unwrap());

    let servo = {
        let geometry = view.get_geometry();
        let waker = window.create_event_loop_waker();
        Servo::new(geometry, view.clone(), waker)
    };

    let home_url = App::get_resources_path().unwrap().parent().unwrap().join("shell_resources").join("home.html");
    let home_url = ServoUrl::from_file_path(&home_url).unwrap().into_string();

    // Skip first argument (executable), and find the first
    // argument that doesn't start with `-`
    let url = args().skip(1).find(|arg| {
        !arg.starts_with("-")
    }).unwrap_or(home_url);

    let browser = servo.create_browser(&url);
    servo.select_browser(browser.id);

    let mut state = App::get_init_state();
    state.current_window_index = Some(0);
    state.windows.push(Window::get_init_state());
    state.windows[0].current_browser_index = Some(0);
    state.windows[0].browsers.push(browser);
    app.render(&state);
    // FIXME: no mut!
    window.render(&mut state.windows[0]);

    info!("Servo version: {}", servo.version());

    // Use a RefCell, otherwise the handle_events callback needs to be a FnMut, making things a bit hard
    // FIXME: do not use a RefCell
    let state = RefCell::new(state);

    let handle_events = || {

        let mut state = state.borrow_mut();

        // Loop until no events are available anymore.
        loop {

            let app_events = app.get_events();
            let win_events = window.get_events();
            let view_events = view.get_events();
            let servo_events = servo.get_events();

            if app_events.is_empty() &&
               win_events.is_empty() &&
               view_events.is_empty() &&
               servo_events.is_empty() {
                   break
            }

            // FIXME: it's really annoying we need this
            let mut force_sync = false;
            let mut ui_invalidated = false;

            for event in app_events {
                match event {
                    AppEvent::DidFinishLaunching => {
                        // FIXME: does this work?
                    }
                    AppEvent::WillTerminate => {
                        // FIXME: does this work?
                    }
                    AppEvent::DidChangeScreenParameters => {
                        // FIXME: does this work?
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    AppEvent::DoCommand(cmd) => {
                        match cmd {
                            AppCommand::ClearHistory => {
                                // FIXME
                            }
                            AppCommand::ToggleOptionDarkTheme => {
                                state.dark_theme = !state.dark_theme;
                                ui_invalidated = true;
                            }
                        }
                    }
                }
            }

            for event in win_events {
                match event {
                    WindowEvent::EventLoopAwaken => {
                        force_sync = true;
                    }
                    WindowEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    WindowEvent::DidEnterFullScreen => {
                        // FIXME
                    }
                    WindowEvent::DidExitFullScreen => {
                        // FIXME
                    }
                    WindowEvent::WillClose => {
                        // FIXME
                    }
                    WindowEvent::OptionsClosed => {
                        state.windows[0].options_open = false;
                    }
                    WindowEvent::UrlbarFocusChanged(focused) => {
                        state.windows[0].urlbar_focused = focused;
                    }
                    WindowEvent::DoCommand(cmd) => {
                        let idx = state.windows[0].current_browser_index.unwrap();
                        let bid = state.windows[0].browsers[idx].id;
                        match cmd {
                            WindowCommand::Stop => {
                                // FIXME
                            }
                            WindowCommand::Reload => {
                                servo.reload(bid);
                            }
                            WindowCommand::NavigateBack => {
                                servo.go_back(bid);
                            }
                            WindowCommand::NavigateForward => {
                                servo.go_forward(bid);
                            }
                            WindowCommand::OpenLocation => {
                                state.windows[0].urlbar_focused = true;
                                ui_invalidated = true;
                            }
                            WindowCommand::OpenInDefaultBrowser => {
                                if let Some(ref url) = state.windows[0].browsers[idx].url {
                                    open::that(url.clone()).ok();
                                }
                            }
                            WindowCommand::ZoomIn => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom *= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomOut => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom /= 1.1;
                                servo.zoom(state.windows[0].browsers[idx].zoom);
                            }
                            WindowCommand::ZoomToActualSize => {
                                ui_invalidated = true;
                                state.windows[0].browsers[idx].zoom = 1.0;
                                servo.reset_zoom();
                            }

                            WindowCommand::ToggleSidebar => {
                                state.windows[0].sidebar_is_open = !state.windows[0].sidebar_is_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::ShowOptions => {
                                state.windows[0].options_open = !state.windows[0].options_open;
                                ui_invalidated = true;
                            }

                            WindowCommand::Load(request) => {
                                state.windows[0].browsers[idx].user_input = Some(request.clone());
                                state.windows[0].urlbar_focused = false;
                                let url = ServoUrl::parse(&request).or_else(|error| {
                                    // FIXME: weak
                                    if request.ends_with(".com") || request.ends_with(".org") || request.ends_with(".net") {
                                        ServoUrl::parse(&format!("http://{}", request))
                                    } else {
                                        Err(error)
                                    }
                                }).or_else(|_| {
                                    ServoUrl::parse(&format!("https://duckduckgo.com/html/?q={}", request))
                                });
                                match url {
                                    Ok(url) => {
                                        servo.load_url(bid, url)
                                    },
                                    Err(err) => warn!("Can't parse url: {}", err),
                                }
                            }
                            WindowCommand::ToggleOptionShowLogs => {
                                state.windows[0].logs_visible = !state.windows[0].logs_visible;
                                ui_invalidated = true;
                            },
                            WindowCommand::NewTab => {
                                let browser = servo.create_browser("about:blank");
                                servo.select_browser(browser.id);
                                servo.update_geometry(view.get_geometry());
                                state.windows[0].current_browser_index = Some(idx + 1);
                                state.windows[0].browsers.push(browser);
                                if cfg!(all(not(feature = "force-glutin"), target_os = "macos")) {
                                    // Focus urlbar, but only on cocoa
                                    state.windows[0].urlbar_focused = true;
                                }
                                ui_invalidated = true;
                            },
                            WindowCommand::CloseTab => {
                                if state.windows[0].browsers.len() > 1 {
                                    let id = state.windows[0].browsers[idx].id;
                                    let new_id = if idx == state.windows[0].browsers.len() - 1 {
                                        state.windows[0].current_browser_index = Some(idx - 1);
                                        state.windows[0].browsers[idx - 1].id
                                    } else {
                                        state.windows[0].browsers[idx + 1].id
                                    };
                                    servo.select_browser(new_id);
                                    servo.close_browser(id);
                                    state.windows[0].browsers.remove(idx);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::PrevTab => {
                                let new_idx = if idx == 0 {
                                    state.windows[0].browsers.len() - 1
                                } else {
                                    idx - 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::NextTab => {
                                let new_idx = if idx == state.windows[0].browsers.len() - 1 {
                                    0
                                } else {
                                    idx + 1
                                };
                                state.windows[0].current_browser_index = Some(new_idx);
                                let id = state.windows[0].browsers[new_idx].id;
                                servo.select_browser(id);
                                ui_invalidated = true;
                            },
                            WindowCommand::SelectTab(idx) => {
                                if state.windows[0].current_browser_index != Some(idx) {
                                    state.windows[0].current_browser_index = Some(idx);
                                    let id = state.windows[0].browsers[idx].id;
                                    servo.select_browser(id);
                                    ui_invalidated = true;
                                }
                            },
                            WindowCommand::ToggleOptionFragmentBorders => { },
                            WindowCommand::ToggleOptionParallelDisplayListBuidling => { },
                            WindowCommand::ToggleOptionShowParallelLayout => { },
                            WindowCommand::ToggleOptionConvertMouseToTouch => { },
                            WindowCommand::ToggleOptionTileBorders => { },

                            WindowCommand::ToggleOptionWRProfiler => {
                                state.windows[0].debug_options.wr_profiler = !state.windows[0].debug_options.wr_profiler;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::Profiler);
                            },

                            WindowCommand::ToggleOptionWRTextureCacheDebug => {
                                state.windows[0].debug_options.wr_texture_cache_debug = !state.windows[0].debug_options.wr_texture_cache_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::TextureCacheDebug);
                            },

                            WindowCommand::ToggleOptionWRTargetDebug => {
                                state.windows[0].debug_options.wr_render_target_debug = !state.windows[0].debug_options.wr_render_target_debug;
                                servo.toggle_webrender_debug_option(WebRenderDebugOption::RenderTargetDebug);
                            },
                        }
                    }
                }
            }

            for event in view_events {
                let idx = state.windows[0].current_browser_index.unwrap();
                let state = &mut state.windows[0].browsers[idx];
                match event {
                    ViewEvent::GeometryDidChange => {
                        servo.update_geometry(view.get_geometry());
                        view.update_drawable();
                    }
                    ViewEvent::MouseWheel(delta, phase) => {
                        let (mut x, mut y) = match delta {
                            view::MouseScrollDelta::PixelDelta(x, y) => (x, y),
                            _ => (0.0, 0.0),
                        };
                        if y.abs() >= x.abs() { x = 0.0; } else { y = 0.0; }
                        servo.perform_scroll(0, 0, x, y, phase);
                    }
                    ViewEvent::MouseMoved(x, y) => {
                        state.last_mouse_point = (x, y);
                        servo.perform_mouse_move(x, y);
                    }
                    ViewEvent::MouseInput(element_state, button) => {
                        let (x, y) = state.last_mouse_point;
                        let (org_x, org_y) = state.last_mouse_down_point;
                        let last_mouse_down_button = state.last_mouse_down_button;
                        servo.perform_click(x, y, org_x, org_y, element_state, button, last_mouse_down_button);
                        state.last_mouse_down_point = (x, y);
                        if element_state == view::ElementState::Pressed {
                            state.last_mouse_down_button = Some(button);
                        }
                    }
                    ViewEvent::KeyEvent(c, key, keystate, modifiers) => {
                        servo.send_key(state.id, c, key, keystate, modifiers);
                    }
                }
            }

            for event in servo_events {
                match event {
                    ServoEvent::SetWindowInnerSize(..) => {
                        // ignore
                    }
                    ServoEvent::SetWindowPosition(..) => {
                        // ignore
                    }
                    ServoEvent::SetFullScreenState(fullscreen) => {
                        if fullscreen {
                            view.enter_fullscreen();
                        } else {
                            view.exit_fullscreen();
                        }
                    }
                    ServoEvent::TitleChanged(id, title) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.title = title;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::StatusChanged(status) => {
                        state.windows[0].status = status;
                        ui_invalidated = true;
                    }
                    ServoEvent::LoadStart(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = true;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::LoadEnd(id) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                browser.is_loading = false;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::HeadParsed(..) => {
                        // FIXME
                    }
                    ServoEvent::HistoryChanged(id, entries, current) => {
                        match state.windows[0].browsers.iter_mut().find(|b| b.id == id) {
                            Some(browser) => {
                                let url = entries[current].url.to_string();
                                browser.url = Some(url);
                                browser.can_go_back = current > 0;
                                browser.can_go_forward = current < entries.len() - 1;
                                ui_invalidated = true;
                            }
                            None => { /*FIXME*/ }
                        }
                    }
                    ServoEvent::CursorChanged(cursor) => {
                        state.cursor = cursor;
                        ui_invalidated = true;
                    }
                    ServoEvent::FaviconChanged(..) => {
                        // FIXME
                    }
                    ServoEvent::Key(..) => {
                        // FIXME
                    }
                    ServoEvent::OpenInDefaultBrowser(url) => {
                        open::that(url).ok();
                    }
                }
            }

            if ui_invalidated {
                app.render(&state);
                window.render(&state.windows[0]);
            }

            servo.sync(force_sync);
        }

        // Here, only stuff that we know for sure won't trigger any
        // new events

        // FIXME: logs will grow until pulled
        if state.windows[0].logs_visible {
            window.append_logs(&logs.get_logs());
        }
    };

    view.set_live_resize_callback(&handle_events);

    app.run(handle_events);

}
<|endoftext|>


<commit_before>use std::io;
use std::io::Write;
use std::process::Command;

fn main() {
    println!("Welcome to sksh");
    loop {
        print!("$ ");
        let line: String = read_line();
        let parsed: Vec<&str> = split_line(&line);
        let (command, args) = match parsed.split_first() {
            Some((first, elements)) => (first.trim(), elements),
            None => {
                return ();
            }
        };

        execute(command, args);
    }
}

fn execute(c: &str, args: &[&str]) {
    let mut trimmed_args = Vec::new();

    for i in args {
        trimmed_args.push(i.trim());
    }

    let s = &trimmed_args[..];

    let output = Command::new(c)
        .args(s)
        .output()
        .expect("failed to execute process.");

    if output.status.success() {
        println!("{}", String::from_utf8_lossy(&output.stdout));
    }
}

fn split_line(line: &str) -> Vec<&str> {
    let v: Vec<&str> = line.split(' ').collect();
    return v;
}

fn read_line() -> String {
    let mut line = String::new();
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut line)
        .expect("Failed to read line");
    return line;
}
<commit_msg>check for empty command<commit_after>use std::io;
use std::io::Write;
use std::process::Command;

fn main() {
    println!("Welcome to sksh");
    loop {
        print!("$ ");
        let line: String = read_line();
        let parsed: Vec<&str> = split_line(&line);
        let (command, args) = match parsed.split_first() {
            Some((first, elements)) => (first.trim(), elements),
            None => {
                return ();
            }
        };

        execute(command, args);
    }
}

fn execute(c: &str, args: &[&str]) {
    if c.len() == 0 {
        println!("");
        return;
    }

    let mut trimmed_args = Vec::new();

    for i in args {
        trimmed_args.push(i.trim());
    }

    let s = &trimmed_args[..];

    let output = Command::new(c)
        .args(s)
        .output()
        .expect("failed to execute process.");

    if output.status.success() {
        println!("{}", String::from_utf8_lossy(&output.stdout));
    }
}

fn split_line(line: &str) -> Vec<&str> {
    let v: Vec<&str> = line.split(' ').collect();
    return v;
}

fn read_line() -> String {
    let mut line = String::new();
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut line)
        .expect("Failed to read line");
    return line;
}
<|endoftext|>


<commit_before>extern crate fuse;
extern crate libc;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate clap;

use std::collections::BTreeMap;
use std::path::Path;
use std::env;
use std::io::prelude::Read;
use libc::{ENOENT, ENOSYS};
use time::Timespec;
use fuse::{FileAttr, FileType, Filesystem, Request, ReplyAttr, ReplyData, ReplyEntry, ReplyDirectory, ReplyOpen};
use hyper::client::{Client, Response};
use rustc_serialize::json::Json;
use clap::{App, Arg};

struct TwitchFileSystem {
    attrs: BTreeMap<u64, FileAttr>,
    inodes: BTreeMap<String, u64>
}

impl TwitchFileSystem {
    fn new() -> TwitchFileSystem {
        let mut attrs = BTreeMap::new();
        let mut inodes = BTreeMap::new();
        let ts = time::now().to_timespec();
        let attr = FileAttr {
            ino: 1,
            size: 0,
            blocks: 0,
            atime: ts,
            mtime: ts,
            ctime: ts,
            crtime: ts,
            kind: FileType::Directory,
            perm: 0o755,
            nlink: 0,
            uid: 0,
            gid: 0,
            rdev: 0,
            flags: 0
        };
        attrs.insert(1, attr);
        inodes.insert("/".to_owned(), 1);
        let mut body = String::new();
        Client::new()
            .get("https://api.twitch.tv/kraken/games/top")
            .send()
            .expect("Couldn't load twitch")
            .read_to_string(&mut body);

        match Json::from_str(&body) {
            Ok(data) => {
                let games = data.find("top").unwrap().as_array().unwrap();
                for (i, game) in games.iter().enumerate() {
                    let attr = FileAttr {
                        ino: i as u64 + 2,
                        size: 0,
                        blocks: 0,
                        atime: ts,
                        mtime: ts,
                        ctime: ts,
                        crtime: ts,
                        kind: FileType::RegularFile,
                        perm: 0o644,
                        nlink: 0,
                        uid: 0,
                        gid: 0,
                        rdev: 0,
                        flags: 0
                    };
                    let name = game
                        .find_path(&["game", "name"])
                        .unwrap()
                        .as_string()
                        .unwrap();

                    attrs.insert(attr.ino, attr);
                    inodes.insert(name.to_owned(), attr.ino);
                }
            },
            Err(_) => println!("Twitch returned invalid json")
        }
        TwitchFileSystem {attrs: attrs, inodes: inodes}
    }
}

impl Filesystem for TwitchFileSystem {
    fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match self.attrs.get(&ino) {
            Some(attr) => {
                let ttl = Timespec::new(1, 0);
                reply.attr(&ttl, attr);
            },
            None => reply.error(ENOENT)
        }
    }

    fn readdir(&mut self, _req: &Request, ino: u64, fh: u64, offset: u64, mut reply: ReplyDirectory) {
        if offset == 0 {

            reply.add(1, 0, FileType::Directory, &Path::new("."));
            reply.add(1, 1, FileType::Directory, &Path::new(".."));
            reply.add(1, 29, FileType::RegularFile, &Path::new("test"));
        }

        reply.ok();
    }
    fn read(&mut self, _req: &Request, ino: u64, fh: u64, offset: u64, size: u32, reply: ReplyData) {
        reply.data("test".as_bytes());
    }
}

fn main() {
    let matches = App::new("twitch-fs")
        .version(option_env!("CARGO_PKG_VERSION").unwrap_or("unknown version"))
        .arg(Arg::with_name("mountpoint")
             .index(1)
             .required(true))
        .get_matches();

    // unwrap() is safe here because the argument is set as required
    let mountpoint = matches.value_of_os("mountpoint").unwrap();
    let fs = TwitchFileSystem::new();

    fuse::mount(fs , &mountpoint, &[])
}
<commit_msg>Fix readdirs<commit_after>extern crate fuse;
extern crate libc;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate clap;

use std::collections::BTreeMap;
use std::path::Path;
use std::env;
use std::io::prelude::Read;
use libc::{ENOENT, ENOSYS};
use time::Timespec;
use fuse::{FileAttr, FileType, Filesystem, Request, ReplyAttr, ReplyData, ReplyEntry, ReplyDirectory, ReplyOpen};
use hyper::client::{Client, Response};
use rustc_serialize::json::Json;
use clap::{App, Arg};

struct TwitchFileSystem {
    attrs: BTreeMap<u64, FileAttr>,
    inodes: BTreeMap<String, u64>
}

impl TwitchFileSystem {
    fn new() -> TwitchFileSystem {
        let mut attrs = BTreeMap::new();
        let mut inodes = BTreeMap::new();
        let ts = time::now().to_timespec();
        let attr = FileAttr {
            ino: 1,
            size: 0,
            blocks: 0,
            atime: ts,
            mtime: ts,
            ctime: ts,
            crtime: ts,
            kind: FileType::Directory,
            perm: 0o755,
            nlink: 0,
            uid: 0,
            gid: 0,
            rdev: 0,
            flags: 0
        };
        attrs.insert(1, attr);
        inodes.insert("/".to_owned(), 1);
        let mut body = String::new();
        Client::new()
            .get("https://api.twitch.tv/kraken/games/top")
            .send()
            .expect("Couldn't load twitch")
            .read_to_string(&mut body);

        match Json::from_str(&body) {
            Ok(data) => {
                let games = data.find("top").unwrap().as_array().unwrap();
                for (i, game) in games.iter().enumerate() {
                    let attr = FileAttr {
                        ino: i as u64 + 2,
                        size: 0,
                        blocks: 0,
                        atime: ts,
                        mtime: ts,
                        ctime: ts,
                        crtime: ts,
                        kind: FileType::RegularFile,
                        perm: 0o644,
                        nlink: 0,
                        uid: 0,
                        gid: 0,
                        rdev: 0,
                        flags: 0
                    };
                    let name = game
                        .find_path(&["game", "name"])
                        .unwrap()
                        .as_string()
                        .unwrap();

                    attrs.insert(attr.ino, attr);
                    inodes.insert(name.to_owned(), attr.ino);
                }
            },
            Err(_) => println!("Twitch returned invalid json")
        }
        TwitchFileSystem {attrs: attrs, inodes: inodes}
    }
}

impl Filesystem for TwitchFileSystem {
    fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match self.attrs.get(&ino) {
            Some(attr) => {
                let ttl = Timespec::new(1, 0);
                reply.attr(&ttl, attr);
            },
            None => reply.error(ENOENT)
        }
    }

    fn readdir(&mut self, _req: &Request, ino: u64, fh: u64, offset: u64, mut reply: ReplyDirectory) {
        if offset == 0 {
            for (game, &inode) in &self.inodes {
                if inode == 1 { continue; }
                let offset = inode;
                reply.add(inode, offset, FileType::RegularFile, &Path::new(game));
            }
            reply.add(1, 0, FileType::Directory, &Path::new("."));
            reply.add(1, 1, FileType::Directory, &Path::new(".."));
        }

        reply.ok();
    }
    fn read(&mut self, _req: &Request, ino: u64, fh: u64, offset: u64, size: u32, reply: ReplyData) {
        reply.data("test".as_bytes());
    }
}

fn main() {
    let matches = App::new("twitch-fs")
        .version(option_env!("CARGO_PKG_VERSION").unwrap_or("unknown version"))
        .arg(Arg::with_name("mountpoint")
             .index(1)
             .required(true))
        .get_matches();

    // unwrap() is safe here because the argument is set as required
    let mountpoint = matches.value_of_os("mountpoint").unwrap();
    let fs = TwitchFileSystem::new();

    fuse::mount(fs , &mountpoint, &[])
}
<|endoftext|>


<commit_before>// #![feature(plugin)]
// #![plugin(clippy)]
// #![deny(clippy)]

#[macro_use]
extern crate serde_derive;
extern crate docopt;

mod cli;
mod cmd;
mod rules;
mod yaml;

use std::fs::File;
use std::io;
#[warn(unused_imports)]
use std::io::prelude::*;

use cli::*;

use docopt::Docopt;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USAGE: &'static str = "
Funzzy the watcher.

Usage:
  funzzy
  funzzy init
  funzzy <command>
  funzzy watch [--verbose]
  funzzy watch [--verbose | -c | -s] <command>
  funzzy run [--verbose] <command> <interval>
  funzzy [options]

Options:
  run               Execute command in a given interval (seconds)
  -h --help         Shows this message.
  -v --version      Shows version.
  --verbose         Use verbose output.
  -c                Execute given command for current folder.
";

#[derive(Debug, Deserialize)]
pub struct Args {
    // comand
    pub cmd_init: bool,
    pub cmd_watch: bool,
    pub cmd_run: bool,

    pub arg_command: String,
    pub arg_interval: u64,

    // options
    pub flag_c: bool,
    pub flag_h: bool,
    pub flag_v: bool,
    pub flag_verbose: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    match args {
        // Metainfo
        Args { flag_v: true, .. } => show(VERSION),
        Args { flag_h: true, .. } => show(USAGE),

        // Commands
        Args { cmd_init: true, .. } => execute(InitCommand::new(cli::watch::DEFAULT_FILENAME)),

        Args { cmd_run: true, .. } => execute(RunCommand::new(args.arg_command, args.arg_interval)),

        Args {
            cmd_watch: true,
            flag_c: true,
            ..
        } => {
            let watches = Watches::from_args(args.arg_command);
            execute(WatchCommand::new(watches, args.flag_verbose))
        }

        Args {
            ref arg_command, ..
        } if !arg_command.is_empty() => {
            match from_stdin() {
                Some(content) => {
                    let watches = Watches::new(rules::from_string(content, arg_command));
                    execute(WatchCommand::new(watches, args.flag_verbose));
                }
                None => show("Nothing to run"),
            };
        }

        _ => {
            let watches = Watches::from(&from_file(cli::watch::DEFAULT_FILENAME));
            execute(WatchCommand::new(watches, args.flag_verbose));
        }
    }
}

fn execute<T: Command>(command: T) {
    if let Err(err) = command.execute() {
        println!("Error: {}", err);
    }
}

fn from_stdin() -> Option<String> {
    let mut buffer = String::new();
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    match handle.read_to_string(&mut buffer) {
        Ok(bytes) => {
            if bytes > 0 {
                Some(buffer)
            } else {
                None
            }
        }
        Err(err) => panic!("Error while reading stdin {}", err),
    }
}

fn from_file(filename: &str) -> String {
    let mut file = match File::open(filename) {
        Ok(f) => f,
        Err(err) => show(
            format!(
                "File {} cannot be opened. Cause: {}",
                cli::watch::DEFAULT_FILENAME,
                err
            )
            .as_str(),
        ),
    };

    let mut content = String::new();
    if let Err(err) = file.read_to_string(&mut content) {
        panic!("Error while trying read file. {}", err);
    }

    content
}

fn show(text: &str) -> ! {
    println!("{}", text);
    std::process::exit(0)
}
<commit_msg>fix: change verbose flag<commit_after>// #![feature(plugin)]
// #![plugin(clippy)]
// #![deny(clippy)]

#[macro_use]
extern crate serde_derive;
extern crate docopt;

mod cli;
mod cmd;
mod rules;
mod yaml;

use std::fs::File;
use std::io;
#[warn(unused_imports)]
use std::io::prelude::*;

use cli::*;

use docopt::Docopt;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USAGE: &'static str = "
Funzzy the watcher.

Usage:
  funzzy
  funzzy init
  funzzy <command>
  funzzy watch [-V]
  funzzy watch [-V | -c | -s] <command>
  funzzy run [-V] <command> <interval>
  funzzy [options]

Options:
  run               Execute command in a given interval (seconds)
  -h --help         Shows this message.
  -v --version      Shows version.
  -V                Use verbose output.
  -c                Execute given command for current folder.
";

#[derive(Debug, Deserialize)]
pub struct Args {
    // comand
    pub cmd_init: bool,
    pub cmd_watch: bool,
    pub cmd_run: bool,

    pub arg_command: String,
    pub arg_interval: u64,

    // options
    pub flag_c: bool,
    pub flag_h: bool,
    pub flag_v: bool,
    pub flag_V: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    match args {
        // Metainfo
        Args { flag_v: true, .. } => show(VERSION),
        Args { flag_h: true, .. } => show(USAGE),

        // Commands
        Args { cmd_init: true, .. } => execute(InitCommand::new(cli::watch::DEFAULT_FILENAME)),

        Args { cmd_run: true, .. } => execute(RunCommand::new(args.arg_command, args.arg_interval)),

        Args {
            cmd_watch: true,
            flag_c: true,
            ..
        } => {
            let watches = Watches::from_args(args.arg_command);
            execute(WatchCommand::new(watches, args.flag_V))
        }

        Args {
            ref arg_command, ..
        } if !arg_command.is_empty() => {
            match from_stdin() {
                Some(content) => {
                    let watches = Watches::new(rules::from_string(content, arg_command));
                    execute(WatchCommand::new(watches, args.flag_V));
                }
                None => show("Nothing to run"),
            };
        }

        _ => {
            let watches = Watches::from(&from_file(cli::watch::DEFAULT_FILENAME));
            execute(WatchCommand::new(watches, args.flag_V));
        }
    }
}

fn execute<T: Command>(command: T) {
    if let Err(err) = command.execute() {
        println!("Error: {}", err);
    }
}

fn from_stdin() -> Option<String> {
    let mut buffer = String::new();
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    match handle.read_to_string(&mut buffer) {
        Ok(bytes) => {
            if bytes > 0 {
                Some(buffer)
            } else {
                None
            }
        }
        Err(err) => panic!("Error while reading stdin {}", err),
    }
}

fn from_file(filename: &str) -> String {
    let mut file = match File::open(filename) {
        Ok(f) => f,
        Err(err) => show(
            format!(
                "File {} cannot be opened. Cause: {}",
                cli::watch::DEFAULT_FILENAME,
                err
            )
            .as_str(),
        ),
    };

    let mut content = String::new();
    if let Err(err) = file.read_to_string(&mut content) {
        panic!("Error while trying read file. {}", err);
    }

    content
}

fn show(text: &str) -> ! {
    println!("{}", text);
    std::process::exit(0)
}
<|endoftext|>