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

use spec::{LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut base = super::linux_base::opts();

    // Make sure that the linker/gcc really don't pull in anything, including
    // default objects, libs, etc.
    base.pre_link_args_crt.insert(LinkerFlavor::Gcc, Vec::new());
    base.pre_link_args_crt.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());

    // At least when this was tested, the linker would not add the
    // `GNU_EH_FRAME` program header to executables generated, which is required
    // when unwinding to locate the unwinding information. I'm not sure why this
    // argument is *not* necessary for normal builds, but it can't hurt!
    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string());

    // There's a whole bunch of circular dependencies when dealing with MUSL
    // unfortunately. To put this in perspective libc is statically linked to
    // liblibc and libunwind is statically linked to libstd:
    //
    // * libcore depends on `fmod` which is in libc (transitively in liblibc).
    //   liblibc, however, depends on libcore.
    // * compiler-rt has personality symbols that depend on libunwind, but
    //   libunwind is in libstd which depends on compiler-rt.
    //
    // Recall that linkers discard libraries and object files as much as
    // possible, and with all the static linking and archives flying around with
    // MUSL the linker is super aggressively stripping out objects. For example
    // the first case has fmod stripped from liblibc (it's in its own object
    // file) so it's not there when libcore needs it. In the second example all
    // the unused symbols from libunwind are stripped (each is in its own object
    // file in libstd) before we end up linking compiler-rt which depends on
    // those symbols.
    //
    // To deal with these circular dependencies we just force the compiler to
    // link everything as a group, not stripping anything out until everything
    // is processed. The linker will still perform a pass to strip out object
    // files but it won't do so until all objects/archives have been processed.
    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-(".to_string());
    base.post_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-)".to_string()]);

    // When generating a statically linked executable there's generally some
    // small setup needed which is listed in these files. These are provided by
    // a musl toolchain and are linked by default by the `musl-gcc` script. Note
    // that `gcc` also does this by default, it just uses some different files.
    //
    // Each target directory for musl has these object files included in it so
    // they'll be included from there.
    base.pre_link_objects_exe_crt.push("crt1.o".to_string());
    base.pre_link_objects_exe_crt.push("crti.o".to_string());
    base.post_link_objects_crt.push("crtn.o".to_string());

    // These targets statically link libc by default
    base.crt_static_default = true;
    // These targets allow the user to choose between static and dynamic linking.
    base.crt_static_respected = true;

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

use spec::{LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
    let mut base = super::linux_base::opts();

    // Make sure that the linker/gcc really don't pull in anything, including
    // default objects, libs, etc.
    base.pre_link_args_crt.insert(LinkerFlavor::Gcc, Vec::new());
    base.pre_link_args_crt.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());

    // At least when this was tested, the linker would not add the
    // `GNU_EH_FRAME` program header to executables generated, which is required
    // when unwinding to locate the unwinding information. I'm not sure why this
    // argument is *not* necessary for normal builds, but it can't hurt!
    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string());

    // When generating a statically linked executable there's generally some
    // small setup needed which is listed in these files. These are provided by
    // a musl toolchain and are linked by default by the `musl-gcc` script. Note
    // that `gcc` also does this by default, it just uses some different files.
    //
    // Each target directory for musl has these object files included in it so
    // they'll be included from there.
    base.pre_link_objects_exe_crt.push("crt1.o".to_string());
    base.pre_link_objects_exe_crt.push("crti.o".to_string());
    base.post_link_objects_crt.push("crtn.o".to_string());

    // These targets statically link libc by default
    base.crt_static_default = true;
    // These targets allow the user to choose between static and dynamic linking.
    base.crt_static_respected = true;

    base
}
<|endoftext|>


<commit_before><commit_msg>Add an example for drawing a persistent point cloud.<commit_after>extern crate kiss3d;
extern crate nalgebra as na;

use kiss3d::resource::{Effect, ShaderAttribute, ShaderUniform, GPUVec,
                       BufferType, AllocationType};
use kiss3d::context::Context;
use kiss3d::planar_camera::PlanarCamera;
use kiss3d::renderer::Renderer;
use kiss3d::post_processing::PostProcessingEffect;
use kiss3d::window::{Window, State};
use kiss3d::camera::Camera;
use na::{Point2, Point3, Vector3, Matrix4};
use kiss3d::text::Font;

// Custom renderers are used to allow rendering objects that are not necessarily
// represented as meshes. In this example, we will render a large, growing, point cloud
// with a color associated to each point.

// Writing a custom renderer requires the main loop to be
// handled by the `State` trait instead of a `while window.render()`
// like other examples.

struct AppState {
    point_cloud_renderer: PointCloudRenderer,
}

impl State for AppState {
    // Return the custom renderer that will be called at each
    // render loop.
    fn cameras_and_effect_and_renderer(&mut self) -> (
        Option<&mut dyn Camera>,
        Option<&mut dyn PlanarCamera>,
        Option<&mut dyn Renderer>,
        Option<&mut dyn PostProcessingEffect>,
    ) {
        (None, None, Some(&mut self.point_cloud_renderer), None)
    }

    fn step(&mut self, window: &mut Window) {
        if self.point_cloud_renderer.num_points() < 1_000_000 {
            // Add some random points to the point cloud.
            for _ in 0..1_000 {
                let random: Point3<f32> = rand::random();
                self.point_cloud_renderer.push( (random - Vector3::repeat(0.5)) * 0.5, rand::random());
            }
        }

        let num_points_text = format!("Number of points: {}", self.point_cloud_renderer.num_points());
        window.draw_text(&num_points_text, &Point2::new(0.0, 20.0), 60.0, &Font::default(), &Point3::new(1.0, 1.0, 1.0));
    }
}

fn main() {
    let window = Window::new("Kiss3d: persistent_point_cloud");
    let app = AppState {
        point_cloud_renderer: PointCloudRenderer::new(4.0)
    };

    window.render_loop(app)
}

/// Structure which manages the display of long-living points.
struct PointCloudRenderer {
    shader: Effect,
    pos: ShaderAttribute<Point3<f32>>,
    color: ShaderAttribute<Point3<f32>>,
    proj: ShaderUniform<Matrix4<f32>>,
    view: ShaderUniform<Matrix4<f32>>,
    colored_points: GPUVec<Point3<f32>>,
    point_size: f32,
}

impl PointCloudRenderer {
    /// Creates a new points renderer.
    fn new(point_size: f32) -> PointCloudRenderer {
        let mut shader = Effect::new_from_str(VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC);

        shader.use_program();

        PointCloudRenderer {
            colored_points: GPUVec::new(Vec::new(), BufferType::Array, AllocationType::StreamDraw),
            pos: shader.get_attrib::<Point3<f32>>("position").unwrap(),
            color: shader.get_attrib::<Point3<f32>>("color").unwrap(),
            proj: shader.get_uniform::<Matrix4<f32>>("proj").unwrap(),
            view: shader.get_uniform::<Matrix4<f32>>("view").unwrap(),
            shader,
            point_size,
        }
    }

    fn push(&mut self, point: Point3<f32>, color: Point3<f32>) {
        if let Some(colored_points) = self.colored_points.data_mut() {
            colored_points.push(point);
            colored_points.push(color);
        }
    }

    fn num_points(&self) -> usize {
        self.colored_points.len() / 2
    }
}

impl Renderer for PointCloudRenderer {
    /// Actually draws the points.
    fn render(&mut self, pass: usize, camera: &mut dyn Camera) {
        if self.colored_points.len() == 0 {
            return;
        }

        self.shader.use_program();
        self.pos.enable();
        self.color.enable();

        camera.upload(pass, &mut self.proj, &mut self.view);

        self.color.bind_sub_buffer(&mut self.colored_points, 1, 1);
        self.pos.bind_sub_buffer(&mut self.colored_points, 1, 0);

        let ctxt = Context::get();
        ctxt.point_size(self.point_size);
        ctxt.draw_arrays(Context::POINTS, 0, (self.colored_points.len() / 2) as i32);

        self.pos.disable();
        self.color.disable();
    }
}

const VERTEX_SHADER_SRC: &'static str = "#version 100
    attribute vec3 position;
    attribute vec3 color;
    varying   vec3 Color;
    uniform   mat4 proj;
    uniform   mat4 view;
    void main() {
        gl_Position = proj * view * vec4(position, 1.0);
        Color = color;
    }";

const FRAGMENT_SHADER_SRC: &'static str = "#version 100
#ifdef GL_FRAGMENT_PRECISION_HIGH
   precision highp float;
#else
   precision mediump float;
#endif

    varying vec3 Color;
    void main() {
        gl_FragColor = vec4(Color, 1.0);
    }";
<|endoftext|>


<commit_before><commit_msg>add min and max functions<commit_after><|endoftext|>


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

// compile-flags: -O

#![crate_type = "lib"]

// CHECK-LABEL: @issue_34947
#[no_mangle]
pub fn issue_34947(x: i32) -> i32 {
    // CHECK: mul
    // CHECK-NEXT: mul
    // CHECK-NEXT: mul
    // CHECK-NEXT: ret
    x.pow(5)
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary clone() call<commit_after><|endoftext|>


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

// compile-flags: -O

#![crate_type = "lib"]

// CHECK-LABEL: @issue_34947
#[no_mangle]
pub fn issue_34947(x: i32) -> i32 {
    // CHECK: mul
    // CHECK-NEXT: mul
    // CHECK-NEXT: mul
    // CHECK-NEXT: ret
    x.pow(5)
}
<|endoftext|>


<commit_before><commit_msg>add downcasting example<commit_after>extern crate skim;
use skim::prelude::*;

/// This example illustrates downcasting custom structs that implement
/// `SkimItem` after calling `Skim::run_with`.

#[derive(Debug, Clone)]
struct Item {
    text: String,
}

impl SkimItem for Item {
    fn text(&self) -> Cow<str> {
        Cow::Borrowed(&self.text)
    }

    fn preview(&self, _context: PreviewContext) -> ItemPreview {
        ItemPreview::Text(self.text.to_owned())
    }
}

pub fn main() {
    let options = SkimOptionsBuilder::default()
        .height(Some("50%"))
        .multi(true)
        .preview(Some(""))
        .build()
        .unwrap();

    let (tx, rx): (SkimItemSender, SkimItemReceiver) = unbounded();

    tx.send(Arc::new(Item { text: "a".to_string() })).unwrap();
    tx.send(Arc::new(Item { text: "b".to_string() })).unwrap();
    tx.send(Arc::new(Item { text: "c".to_string() })).unwrap();

    drop(tx);

    let selected_items = Skim::run_with(&options, Some(rx))
        .map(|out| out.selected_items)
        .unwrap_or_else(|| Vec::new())
        .iter()
        .map(|selected_item| (**selected_item).as_any().downcast_ref::<Item>().unwrap().to_owned())
        .collect::<Vec<Item>>();

    for item in selected_items {
        println!("{:?}", item);
    }
}
<|endoftext|>


<commit_before><commit_msg>working with example server<commit_after>/* This example communicates with the server example. It has following functionality:
   It periodically calls com.example.dbustest.Hello method on  "/hello" object on
   com.example.dbustest service.

   In the meantime, this example reacts to HelloHappened signal which is sent by the server.
*/

extern crate dbus;
extern crate dbus_tokio;
extern crate tokio_core;
extern crate tokio_timer;
extern crate futures;

use dbus::*;

use std::rc::Rc;
use tokio_core::reactor::Core;
use tokio_timer::Timer;
use std::time::Duration;
use futures::{Stream, Future};
use dbus_tokio::AConnection;

fn main() {
    // Let's start by starting up a connection to the session bus. We do not register a name
    // because we do not intend to expose any objects on the bus.
    let c = Rc::new(Connection::get_private(BusType::System).unwrap());

    // To receive D-Bus signals we need to add match that defines which signals should be forwarded
    // to our application.
    c.add_match("type=signal,sender=com.example.dbustest,member=HelloHappened").unwrap();

    // Create Tokio event loop along with asynchronous connection object
    let mut core = Core::new().unwrap();
    let aconn = AConnection::new(c.clone(), core.handle()).unwrap();

    // Create interval - a Stream that will fire an event periodically
    let timer = Timer::default();
    let interval = timer.interval(Duration::from_secs(2));

    // Handle timer errors. Additionally this erases error type from Stream signature.
    let interval = interval.map_err(|e| panic!("TimerError: {}", e) );

    // Create a future calling D-Bus method each time the interval generates a tick
    let calls = interval.for_each(|_| {
        println!("Calling Hello...");
        //TODO: try to handle error when calling on "/"
        let m = Message::new_method_call("com.example.dbustest", "/hello", "com.example.dbustest", "Hello").unwrap();
        aconn.method_call(m).unwrap().then(|reply| {
            let m = reply.unwrap();
            let msg: &str = m.get1().unwrap();
            println!("{}", msg);
            Ok(())
        })
    });

    // Create stream of all incoming D-Bus messages. On top of the messages stream create future,
    // running forever, handling all incoming messages
    let messages = aconn.messages().unwrap();
    let signals = messages.for_each(|m| {
        let headers = m.headers();
        let member = headers.3.unwrap();
        if member == "HelloHappened" {
            let arg1 : &str = m.get1().unwrap();
            println!("Hello from {} happened on the bus!", arg1)
        } else {
            println!("Unprocessed message: {:?}", m)
        }
        Ok(())
    });

    // Simultaneously run signal handling and method calling
    core.run(signals.join(calls)).unwrap();
}

<|endoftext|>


<commit_before><commit_msg>FEAT(core): Update `get`<commit_after><|endoftext|>


<commit_before><commit_msg>Fix(sync): text syncfiles are in native form, not canonical, so use native for diffs.<commit_after><|endoftext|>


<commit_before><commit_msg>Add Store::exists() for checking whether a StoreId exists as Entry<commit_after><|endoftext|>


<commit_before><commit_msg>Add example of color effects<commit_after>//! Demonstrates adding a color tint and applying a color gradient to a grayscale image.

extern crate image;
extern crate imageproc;

use std::env;
use std::path::Path;
use image::{Luma, open, Rgb};
use imageproc::map::map_colors;
use imageproc::pixelops::weighted_sum;

/// Tint a grayscale value with the given color.
/// Midtones are tinted most heavily.
pub fn tint(gray: Luma<u8>, color: Rgb<u8>) -> Rgb<u8> {
    let dist_from_mid = ((gray[0] as f32 - 128f32).abs()) / 255f32;
    let scale_factor = 1f32 - 4f32 * dist_from_mid.powi(2);
    weighted_sum(Rgb([gray[0]; 3]), color, 1.0, scale_factor)
}

/// Linearly interpolates between low and mid colors for pixel intensities less than
/// half of maximum brightness and between mid and high for those above.
pub fn color_gradient(gray: Luma<u8>, low: Rgb<u8>, mid: Rgb<u8>, high: Rgb<u8>) -> Rgb<u8> {
    let fraction = gray[0] as f32 / 255f32;
    let (lower, upper, offset) = if fraction < 0.5 { (low, mid, 0.0) } else { (mid, high, 0.5) };
    let right_weight = 2.0 * (fraction - offset);
    let left_weight = 1.0 - right_weight;
    weighted_sum(lower, upper, left_weight, right_weight)
}

fn main() {

    let arg = if env::args().count() == 2 {
            env::args().nth(1).unwrap()
        } else {
            panic!("Please enter an input file")
        };
    let path = Path::new(&arg);

    // Load a image::DynamicImage and convert it to a image::GrayImage
    let image = open(path)
        .ok()
        .expect(&format!("Could not load image at {:?}", path))
        .to_luma();

    let blue = Rgb([0u8, 0u8, 255u8]);

    // Apply the color tint to every pixel in the grayscale image, producing a image::RgbImage
    let tinted = map_colors(&image, |pix| tint(pix, blue));
    let _ = tinted.save(path.with_file_name("tinted.png")).unwrap();

    // Apply color gradient to each image pixel
    let black = Rgb([0u8, 0u8, 0u8]);
    let red = Rgb([255u8, 0u8, 0u8]);
    let yellow = Rgb([255u8, 255u8, 0u8]);
    let gradient = map_colors(&image, |pix| color_gradient(pix, black, red, yellow));
    let _ = gradient.save(path.with_file_name("gradient.png")).unwrap();
}
<|endoftext|>


<commit_before>use std::io::{Result, SeekFrom};
use std::syscall::*;
use std::Url;

pub struct Resource;

impl Resource {
    pub fn dup(&self) -> Result<Box<Resource>> {
        Ok(box Resource)
    }

    pub fn path(&self) -> Result<String> {
        Ok(format!(""))
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        Ok(0)
    }

    pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
        Ok(0)
    }

    pub fn seek(&mut self, _: SeekFrom) -> Result<u64> {
        Err(SysError::new(ESPIPE))
    }

    pub fn sync(&mut self) -> Result<()> {
        Ok(())
    }
}

pub struct Scheme;

impl Scheme {
    pub fn new() -> Box<Scheme> {
        box Scheme
    }

    pub fn open(&mut self, url_str: &str, _: usize) -> Result<Box<Resource>> {
        Err(SysError::new(ENOENT))
    }
}
<commit_msg>Fix merge after reexport fix<commit_after>use std::io::{Result, SeekFrom};
use std::syscall::*;
use std::url::Url;

pub struct Resource;

impl Resource {
    pub fn dup(&self) -> Result<Box<Resource>> {
        Ok(box Resource)
    }

    pub fn path(&self) -> Result<String> {
        Ok(format!(""))
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        Ok(0)
    }

    pub fn write(&mut self, buf: &[u8]) -> Result<usize> {
        Ok(0)
    }

    pub fn seek(&mut self, _: SeekFrom) -> Result<u64> {
        Err(SysError::new(ESPIPE))
    }

    pub fn sync(&mut self) -> Result<()> {
        Ok(())
    }
}

pub struct Scheme;

impl Scheme {
    pub fn new() -> Box<Scheme> {
        box Scheme
    }

    pub fn open(&mut self, url_str: &str, _: usize) -> Result<Box<Resource>> {
        Err(SysError::new(ENOENT))
    }
}
<|endoftext|>


<commit_before><commit_msg>Add padding to Deque to avoid false sharing<commit_after><|endoftext|>


<commit_before>#![deny(warnings)]

extern crate cobalt;
extern crate clap;
extern crate env_logger;
extern crate notify;
extern crate glob;
extern crate ghp;

extern crate hyper;

#[macro_use]
extern crate log;

use clap::{Arg, App, SubCommand, AppSettings};
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use ghp::import_dir;
use glob::Pattern;
use cobalt::create_new_project;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;
use std::io::prelude::*;
use std::io::Result as IoResult;
use std::fs::File;

fn main() {
    let global_matches = App::new("Cobalt")
        .version("0.3.0")
        .author("Benny Klotz <r3qnbenni@gmail.com>, Johann Hofmann")
        .about("A static site generator written in Rust.")
        .setting(AppSettings::SubcommandRequired)
        .setting(AppSettings::GlobalVersion)
        .arg(Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: .cobalt.yml]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("source")
            .short("s")
            .long("source")
            .value_name("DIR")
            .help("Source folder [default: ./]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Destination folder [default: ./]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("layouts")
            .short("l")
            .long("layouts")
            .value_name("DIR")
            .help("Layout templates folder [default: ./_layouts]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("posts")
            .short("p")
            .long("posts")
            .value_name("DIR")
            .help("Posts folder [default: ./posts]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .global(true)
            .takes_value(false))
        .arg(Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false))
        .arg(Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false))
        .subcommand(SubCommand::with_name("new")
            .about("create a new cobalt project")
            .arg(Arg::with_name("DIRECTORY")
                .help("Suppress all output")
                .default_value("./")
                .index(1)))
        .subcommand(SubCommand::with_name("build")
            .about("build the cobalt project at the source dir")
            .arg(Arg::with_name("import")
                .short("i")
                .long("import")
                .help("Import after build to gh-pages branch")
                .takes_value(false))
            .arg(Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true))
            .arg(Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("serve")
            .about("build and serve the cobalt project at the source dir")
            .arg(Arg::with_name("port")
                .short("P")
                .long("port")
                .value_name("INT")
                .help("Port to serve from")
                .default_value("3000")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("watch")
            .about("build, serve, and watch the project at the source dir")
            .arg(Arg::with_name("port")
                .short("P")
                .long("port")
                .value_name("INT")
                .help("Port to serve from")
                .default_value("3000")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("import")
            .about("moves the contents of the dest folder to the gh-pages branch")
            .arg(Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true))
            .arg(Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true)))
        .get_matches();

    let (command, matches) = match global_matches.subcommand() {
        (command, Some(matches)) => (command, matches),
        (_, None) => unreachable!(),
    };

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);

    match matches.value_of("log-level").or(global_matches.value_of("log-level")) {
        Some("error") => builder.filter(None, LogLevelFilter::Error),
        Some("warn") => builder.filter(None, LogLevelFilter::Warn),
        Some("info") => builder.filter(None, LogLevelFilter::Info),
        Some("debug") => builder.filter(None, LogLevelFilter::Debug),
        Some("trace") => builder.filter(None, LogLevelFilter::Trace),
        Some("off") => builder.filter(None, LogLevelFilter::Off),
        _ => builder.filter(None, LogLevelFilter::Info),
    };

    if matches.is_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.is_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = matches.value_of("config")
        .or(global_matches.value_of("config"))
        .unwrap_or(".cobalt.yml")
        .to_string();

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        warn!("No .cobalt.yml file found in current directory, using default config.");
        Default::default()
    };

    config.source = matches.value_of("source")
        .or(global_matches.value_of("source"))
        .map(str::to_string)
        .unwrap_or(config.source);

    config.dest = matches.value_of("destination")
        .or(global_matches.value_of("destination"))
        .map(str::to_string)
        .unwrap_or(config.dest);

    config.layouts = matches.value_of("layouts")
        .or(global_matches.value_of("layouts"))
        .map(str::to_string)
        .unwrap_or(config.layouts);

    config.posts = matches.value_of("posts")
        .or(global_matches.value_of("posts"))
        .map(str::to_string)
        .unwrap_or(config.posts);

    config.include_drafts = matches.is_present("drafts");

    match command {
        "new" => {
            let directory = matches.value_of("DIRECTORY").unwrap();

            match create_new_project(&directory.to_string()) {
                Ok(_) => info!("Created new project at {}", directory),
                Err(e) => {
                    error!("{}", e);
                    error!("Could not create a new cobalt project");
                    std::process::exit(1);
                }
            }
        }

        "build" => {
            build(&config);
            if matches.is_present("import") {
                let branch = matches.value_of("branch").unwrap().to_string();
                let message = matches.value_of("message").unwrap().to_string();
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            let port = matches.value_of("port").unwrap().to_string();
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            let port = matches.value_of("port").unwrap().to_string();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    // get where process was run from
                                    let cwd = std::env::current_dir().unwrap_or(PathBuf::new());

                                    // the final goal is to have a relative path
                                    // without corner-case prefixes like "./"
                                    let abs_path = match path.is_absolute() {
                                        true => path.clone(),
                                        false => {
                                            // let path::Path handle corner cases like `./rel/path`
                                            let mut abs_path = cwd.clone();
                                            abs_path.push(path.clone());
                                            abs_path
                                        }
                                    };
                                    let rel_path = abs_path.strip_prefix(&cwd).unwrap_or(&path);

                                    // check whether this path has been marked as ignored in config
                                    let rel_path_matches =
                                        |pattern| Pattern::matches_path(pattern, rel_path);
                                    let path_ignored = &config.ignore.iter().any(rel_path_matches);

                                    if !path_ignored {
                                        build(&config);
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            let branch = matches.value_of("branch").unwrap().to_string();
            let message = matches.value_of("message").unwrap().to_string();
            import(&config, &branch, &message);
        }

        _ => {
            println!("{}", global_matches.usage());
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn static_file_handler(dest: &str, req: Request, mut res: Response) -> IoResult<()> {
    // grab the requested path
    let req_path = match req.uri {
        RequestUri::AbsolutePath(p) => p,
        _ => {
            // return a 400 and exit from this request
            *res.status_mut() = hyper::status::StatusCode::BadRequest;
            let body = b"<h1> <center> 400: Bad request </center> </h1>";
            try!(res.send(body));
            return Ok(());
        }
    };

    // find the path of the file in the local system
    // (this gets rid of the '/' in `p`, so the `join()` will not replace the
    // path)
    let path = PathBuf::from(dest).join(&req_path[1..]);

    let serve_path = if path.is_file() {
        // try to point the serve path to `path` if it corresponds to a file
        path
    } else {
        // try to point the serve path into a "index.html" file in the requested
        // path
        path.join("index.html")
    };

    // if the request points to a file and it exists, read and serve it
    if serve_path.exists() {
        let mut file = try!(File::open(serve_path));

        // buffer to store the file
        let mut buffer: Vec<u8> = vec![];

        try!(file.read_to_end(&mut buffer));

        try!(res.send(&buffer));
    } else {
        // return a 404 status
        *res.status_mut() = hyper::status::StatusCode::NotFound;

        // write a simple body for the 404 page
        let body = b"<h1> <center> 404: Page not found </center> </h1>";

        try!(res.send(body));
    }

    Ok(())
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);

    let ip = format!("127.0.0.1:{}", port);
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");

    // attempts to create a server
    let http_server = match Server::http(&*ip) {
        Ok(server) => server,
        Err(e) => {
            error!("{}", e);
            std::process::exit(1);
        }
    };

    // need a clone because of closure's lifetime
    let dest_clone = dest.to_owned();

    // bind the handle function and start serving
    if let Err(e) = http_server.handle(move |req: Request, res: Response| {
        if let Err(e) = static_file_handler(&dest_clone, req, res) {
            error!("{}", e);
            std::process::exit(1);
        }
    }) {
        error!("{}", e);
        std::process::exit(1);
    };
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<commit_msg>Improve code style in watch command<commit_after>#![deny(warnings)]

extern crate cobalt;
extern crate clap;
extern crate env_logger;
extern crate notify;
extern crate glob;
extern crate ghp;

extern crate hyper;

#[macro_use]
extern crate log;

use clap::{Arg, App, SubCommand, AppSettings};
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri;
use ghp::import_dir;
use glob::Pattern;
use cobalt::create_new_project;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;
use std::io::prelude::*;
use std::io::Result as IoResult;
use std::fs::File;

fn main() {
    let global_matches = App::new("Cobalt")
        .version("0.3.0")
        .author("Benny Klotz <r3qnbenni@gmail.com>, Johann Hofmann")
        .about("A static site generator written in Rust.")
        .setting(AppSettings::SubcommandRequired)
        .setting(AppSettings::GlobalVersion)
        .arg(Arg::with_name("config")
            .short("c")
            .long("config")
            .value_name("FILE")
            .help("Config file to use [default: .cobalt.yml]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("source")
            .short("s")
            .long("source")
            .value_name("DIR")
            .help("Source folder [default: ./]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("destination")
            .short("d")
            .long("destination")
            .value_name("DIR")
            .help("Destination folder [default: ./]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("layouts")
            .short("l")
            .long("layouts")
            .value_name("DIR")
            .help("Layout templates folder [default: ./_layouts]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("posts")
            .short("p")
            .long("posts")
            .value_name("DIR")
            .help("Posts folder [default: ./posts]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("drafts")
            .long("drafts")
            .help("Include drafts.")
            .global(true)
            .takes_value(false))
        .arg(Arg::with_name("log-level")
            .short("L")
            .long("log-level")
            .possible_values(&["error", "warn", "info", "debug", "trace", "off"])
            .help("Log level [default: info]")
            .global(true)
            .takes_value(true))
        .arg(Arg::with_name("trace")
            .long("trace")
            .help("Log ultra-verbose (trace level) information")
            .global(true)
            .takes_value(false))
        .arg(Arg::with_name("silent")
            .long("silent")
            .help("Suppress all output")
            .global(true)
            .takes_value(false))
        .subcommand(SubCommand::with_name("new")
            .about("create a new cobalt project")
            .arg(Arg::with_name("DIRECTORY")
                .help("Suppress all output")
                .default_value("./")
                .index(1)))
        .subcommand(SubCommand::with_name("build")
            .about("build the cobalt project at the source dir")
            .arg(Arg::with_name("import")
                .short("i")
                .long("import")
                .help("Import after build to gh-pages branch")
                .takes_value(false))
            .arg(Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true))
            .arg(Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("serve")
            .about("build and serve the cobalt project at the source dir")
            .arg(Arg::with_name("port")
                .short("P")
                .long("port")
                .value_name("INT")
                .help("Port to serve from")
                .default_value("3000")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("watch")
            .about("build, serve, and watch the project at the source dir")
            .arg(Arg::with_name("port")
                .short("P")
                .long("port")
                .value_name("INT")
                .help("Port to serve from")
                .default_value("3000")
                .takes_value(true)))
        .subcommand(SubCommand::with_name("import")
            .about("moves the contents of the dest folder to the gh-pages branch")
            .arg(Arg::with_name("branch")
                .short("b")
                .long("branch")
                .value_name("BRANCH")
                .help("Branch that will be used to import the site to")
                .default_value("gh-pages")
                .takes_value(true))
            .arg(Arg::with_name("message")
                .short("m")
                .long("message")
                .value_name("COMMIT-MESSAGE")
                .help("Commit message that will be used on import")
                .default_value("cobalt site import")
                .takes_value(true)))
        .get_matches();

    let (command, matches) = match global_matches.subcommand() {
        (command, Some(matches)) => (command, matches),
        (_, None) => unreachable!(),
    };

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);

    match matches.value_of("log-level").or(global_matches.value_of("log-level")) {
        Some("error") => builder.filter(None, LogLevelFilter::Error),
        Some("warn") => builder.filter(None, LogLevelFilter::Warn),
        Some("info") => builder.filter(None, LogLevelFilter::Info),
        Some("debug") => builder.filter(None, LogLevelFilter::Debug),
        Some("trace") => builder.filter(None, LogLevelFilter::Trace),
        Some("off") => builder.filter(None, LogLevelFilter::Off),
        _ => builder.filter(None, LogLevelFilter::Info),
    };

    if matches.is_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.is_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = matches.value_of("config")
        .or(global_matches.value_of("config"))
        .unwrap_or(".cobalt.yml")
        .to_string();

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        warn!("No .cobalt.yml file found in current directory, using default config.");
        Default::default()
    };

    config.source = matches.value_of("source")
        .or(global_matches.value_of("source"))
        .map(str::to_string)
        .unwrap_or(config.source);

    config.dest = matches.value_of("destination")
        .or(global_matches.value_of("destination"))
        .map(str::to_string)
        .unwrap_or(config.dest);

    config.layouts = matches.value_of("layouts")
        .or(global_matches.value_of("layouts"))
        .map(str::to_string)
        .unwrap_or(config.layouts);

    config.posts = matches.value_of("posts")
        .or(global_matches.value_of("posts"))
        .map(str::to_string)
        .unwrap_or(config.posts);

    config.include_drafts = matches.is_present("drafts");

    match command {
        "new" => {
            let directory = matches.value_of("DIRECTORY").unwrap();

            match create_new_project(&directory.to_string()) {
                Ok(_) => info!("Created new project at {}", directory),
                Err(e) => {
                    error!("{}", e);
                    error!("Could not create a new cobalt project");
                    std::process::exit(1);
                }
            }
        }

        "build" => {
            build(&config);
            if matches.is_present("import") {
                let branch = matches.value_of("branch").unwrap().to_string();
                let message = matches.value_of("message").unwrap().to_string();
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            let port = matches.value_of("port").unwrap().to_string();
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            let port = matches.value_of("port").unwrap().to_string();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    // get where process was run from
                                    let cwd = std::env::current_dir().unwrap_or(PathBuf::new());

                                    // The final goal is to have a relative path. If we already
                                    // have a relative path, we still convert it to an abs path
                                    // first to handle prefix "./" correctly.
                                    let abs_path = if path.is_absolute() {
                                        path.clone()
                                    } else {
                                        cwd.join(&path)
                                    };
                                    let rel_path = abs_path.strip_prefix(&cwd).unwrap_or(&path);

                                    // check whether this path has been marked as ignored in config
                                    let rel_path_matches =
                                        |pattern| Pattern::matches_path(pattern, rel_path);
                                    let path_ignored = &config.ignore.iter().any(rel_path_matches);

                                    if !path_ignored {
                                        build(&config);
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            let branch = matches.value_of("branch").unwrap().to_string();
            let message = matches.value_of("message").unwrap().to_string();
            import(&config, &branch, &message);
        }

        _ => {
            println!("{}", global_matches.usage());
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn static_file_handler(dest: &str, req: Request, mut res: Response) -> IoResult<()> {
    // grab the requested path
    let req_path = match req.uri {
        RequestUri::AbsolutePath(p) => p,
        _ => {
            // return a 400 and exit from this request
            *res.status_mut() = hyper::status::StatusCode::BadRequest;
            let body = b"<h1> <center> 400: Bad request </center> </h1>";
            try!(res.send(body));
            return Ok(());
        }
    };

    // find the path of the file in the local system
    // (this gets rid of the '/' in `p`, so the `join()` will not replace the
    // path)
    let path = PathBuf::from(dest).join(&req_path[1..]);

    let serve_path = if path.is_file() {
        // try to point the serve path to `path` if it corresponds to a file
        path
    } else {
        // try to point the serve path into a "index.html" file in the requested
        // path
        path.join("index.html")
    };

    // if the request points to a file and it exists, read and serve it
    if serve_path.exists() {
        let mut file = try!(File::open(serve_path));

        // buffer to store the file
        let mut buffer: Vec<u8> = vec![];

        try!(file.read_to_end(&mut buffer));

        try!(res.send(&buffer));
    } else {
        // return a 404 status
        *res.status_mut() = hyper::status::StatusCode::NotFound;

        // write a simple body for the 404 page
        let body = b"<h1> <center> 404: Page not found </center> </h1>";

        try!(res.send(body));
    }

    Ok(())
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);

    let ip = format!("127.0.0.1:{}", port);
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");

    // attempts to create a server
    let http_server = match Server::http(&*ip) {
        Ok(server) => server,
        Err(e) => {
            error!("{}", e);
            std::process::exit(1);
        }
    };

    // need a clone because of closure's lifetime
    let dest_clone = dest.to_owned();

    // bind the handle function and start serving
    if let Err(e) = http_server.handle(move |req: Request, res: Response| {
        if let Err(e) = static_file_handler(&dest_clone, req, res) {
            error!("{}", e);
            std::process::exit(1);
        }
    }) {
        error!("{}", e);
        std::process::exit(1);
    };
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before><commit_msg>Split main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>implemented main stub<commit_after>fn main() {
  println!("Hello, World!");
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                info!("Rebuilding cobalt site...");
                                build(&config);
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<commit_msg>fix for watch command on mac atleast.<commit_after>#![deny(warnings)]

extern crate cobalt;
extern crate getopts;
extern crate env_logger;
extern crate notify;
extern crate ghp;

#[macro_use]
extern crate nickel;

#[macro_use]
extern crate log;

use getopts::Options;
use std::env;
use std::fs;
use cobalt::Config;
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;
use nickel::{Nickel, Options as NickelOptions, StaticFilesHandler};
use ghp::import_dir;

use notify::{RecommendedWatcher, Error, Watcher};
use std::sync::mpsc::channel;
use std::thread;
use std::path::PathBuf;

fn print_version() {
    println!("0.2.0");
}

fn print_usage(opts: Options) {
    let usage = concat!("\n\tbuild -- build the cobalt project at the source dir",
                        "\n\tserve -- build and serve the cobalt project at the source dir",
                        "\n\twatch -- build, serve, and watch the project at the source dir",
                        "\n\timport -- moves the contents of the dest folder to the gh-pages branch");
    println!("{}", opts.usage(usage));
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();

    opts.optopt("s", "source", "Source folder, Default: ./", "");
    opts.optopt("d", "destination", "Destination folder, Default: ./", "");
    opts.optopt("c",
                "config",
                "Config file to use, Default: .cobalt.yml",
                "");
    opts.optopt("l",
                "layouts",
                "\tLayout templates folder, Default: _layouts/",
                "");
    opts.optopt("p", "posts", "Posts folder, Default: _posts/", "");
    opts.optopt("P", "port", "Port to serve from, Default: 3000", "");
    opts.optopt("b", "branch", "Branch that will be used to import the site to, Default: gh-pages", "");
    opts.optopt("m", "message", "Commit message that will be used on import, Default: cobalt site import", "");

    opts.optflag("", "debug", "Log verbose (debug level) information");
    opts.optflag("", "trace", "Log ultra-verbose (trace level) information");
    opts.optflag("", "silent", "Suppress all output");
    opts.optflag("i", "import", "Import after build to gh-pages branch");
    opts.optflag("h", "help", "Print this help menu");
    opts.optflag("v", "version", "Display version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    if matches.opt_present("h") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        print_version();
        return;
    }

    let format = |record: &LogRecord| {
        let level = format!("[{}]", record.level()).to_lowercase();
        format!("{:8} {}", level, record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format);
    builder.filter(None, LogLevelFilter::Info);

    if matches.opt_present("debug") {
        builder.filter(None, LogLevelFilter::Debug);
    }

    if matches.opt_present("trace") {
        builder.filter(None, LogLevelFilter::Trace);
    }

    if matches.opt_present("silent") {
        builder.filter(None, LogLevelFilter::Off);
    }

    builder.init().unwrap();

    let config_path = match matches.opt_str("config") {
        Some(config) => config,
        None => "./.cobalt.yml".to_owned(),
    };

    // Fetch config information if available
    let mut config: Config = if fs::metadata(&config_path).is_ok() {
        info!("Using config file {}", &config_path);

        match Config::from_file(&config_path) {
            Ok(config) => config,
            Err(e) => {
                error!("Error reading config file:");
                error!("{}", e);
                std::process::exit(1);
            }
        }
    } else {
        Default::default()
    };

    if let Some(source) = matches.opt_str("s") {
        config.source = source;
    };

    if let Some(dest) = matches.opt_str("d") {
        config.dest = dest;
    };

    if let Some(layouts) = matches.opt_str("layouts") {
        config.layouts = layouts;
    };

    if let Some(posts) = matches.opt_str("posts") {
        config.posts = posts;
    };

    let command = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(opts);
        return;
    };

    // Check for port and set port variable to it
    let port = matches.opt_str("port").unwrap_or("3000".to_owned());
    let branch = matches.opt_str("branch").unwrap_or("gh-pages".to_owned());
    let message = matches.opt_str("message").unwrap_or("cobalt site import".to_owned());
    let should_import = matches.opt_present("import");

    match command.as_ref() {
        "build" => {
            build(&config);
            if should_import {
                import(&config, &branch, &message);
            }
        }

        "serve" => {
            build(&config);
            serve(&config.dest, &port);
        }

        "watch" => {
            build(&config);

            let dest = config.dest.clone();
            thread::spawn(move || {
                serve(&dest, &port);
            });

            let (tx, rx) = channel();
            let w: Result<RecommendedWatcher, Error> = Watcher::new(tx);

            match w {
                Ok(mut watcher) => {
                    // TODO: clean up this unwrap
                    watcher.watch(&config.source).unwrap();
                    info!("Watching {:?} for changes", &config.source);

                    loop {
                        match rx.recv() {
                            Ok(val) => {
                                trace!("file changed {:?}", val);
                                if let Some(path) = val.path {
                                    if path.is_absolute() {
                                        // get where process was run from
                                        let cwd = std::env::current_dir().unwrap_or(PathBuf::new());
                                        // strip absolute path
                                        let rel_path = path.strip_prefix(&cwd).unwrap_or(&cwd);

                                        // check if path starts with the build folder.
                                        if !rel_path.starts_with(&config.dest) {
                                            build(&config);
                                        }

                                    } else {
                                        // check if path starts with build folder.
                                        // TODO: may want to check if it starts `./`
                                        if path.to_str() != Some(&config.dest) {
                                            build(&config);
                                        }
                                    }
                                }
                            }

                            Err(e) => {
                                error!("[Notify Error]: {}", e);
                                std::process::exit(1);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("[Notify Error]: {}", e);
                    std::process::exit(1);
                }
            }
        }

        "import" => {
            import(&config, &branch, &message);
        }

        _ => {
            print_usage(opts);
            return;
        }
    }
}

fn build(config: &Config) {
    info!("Building from {} into {}", config.source, config.dest);
    match cobalt::build(&config) {
        Ok(_) => info!("Build successful"),
        Err(e) => {
            error!("{}", e);
            error!("Build not successful");
            std::process::exit(1);
        }
    };
}

fn serve(dest: &str, port: &str) {
    info!("Serving {:?} through static file server", dest);
    let mut server = Nickel::new();
    server.options = NickelOptions::default().output_on_listen(false);

    server.utilize(StaticFilesHandler::new(dest));

    let ip = "127.0.0.1:".to_owned() + port;
    info!("Server Listening on {}", &ip);
    info!("Ctrl-c to stop the server");
    server.listen(&*ip);
}

fn import(config: &Config, branch: &str, message: &str) {
    info!("Importing {} to {}", config.dest, branch);

    let meta = match fs::metadata(&config.dest) {
        Ok(data) => data,

        Err(e) => {
            error!("{}", e);
            error!("Import not successful");
            std::process::exit(1);
        }
    };

    if meta.is_dir() {
        match import_dir(&config.dest, branch, message) {
            Ok(_) => info!("Import successful"),
            Err(e) => {
                error!("{}", e);
                error!("Import not successful");
                std::process::exit(1);
            }
        }
    } else {
        error!("Build dir is not a directory: {}", config.dest);
        error!("Import not successful");
        std::process::exit(1);
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix indentation<commit_after><|endoftext|>


<commit_before><commit_msg>Silence warning about the capitalization of "Harvey".<commit_after><|endoftext|>


<commit_before><commit_msg>real error handling, more functional style<commit_after><|endoftext|>


<commit_before><commit_msg>Add `connection::ConnectError`<commit_after><|endoftext|>


<commit_before><commit_msg>add pair impl<commit_after>use std::cmp;

use self::ApplyResult::*;
use super::Leading::{self, Top, Bot};

#[derive(Copy, Clone)]
struct SPart(u64);

#[derive(Copy, Clone)]
pub struct SPair {
    a: SPart,
    b: SPart,
}

/// A variable length pair.
#[derive(Clone)]
pub struct VPair {
    data: Vec<u64>,
    /// Who is leading.
    leading: Leading,
    /// How many bits of the first block are shared.
    prefix: u8,
    /// How many bits of the last block are used.
    used: u8,
}

#[derive(Copy, Clone)]
struct VHead {
    data: u64,
    /// How many bits are shared
    prefix: u8,
    /// How many bits are used
    used: u8,
}

impl VPair {
    pub fn new() -> VPair {
        let mut v = Vec::with_capacity(1);
        v.push(0);

        VPair {
            data: v,
            prefix: 0,
            used: 0,
            leading: Top,
        }
    }

    pub fn apply(&self, p: &SPair) -> Option<VPair> {
        let (mut lead, mut follow) = match self.leading {
            Top => (p.a, p.b),
            Bot => (p.b, p.a),
        };

        let mut head = self.head();

        match head.apply(&mut follow, &mut lead) {
            Mismatch => None,
            Match => Some(self.with_offset_prefix_and_add_lead(0, head.prefix, lead)),
            LeadSwitch => Some(self.switched_with_new_lead(follow)),
            MatchRemaining => {
                let mut head2 = self.head2();

                match self.head2().apply(&mut follow, &mut lead) {
                    Mismatch => None,
                    Match => Some(self.with_offset_prefix_and_add_lead(1, head.prefix, lead)),
                    LeadSwitch => Some(self.switched_with_new_lead(follow)),
                    MatchRemaining => unreachable!("SPairs contain at most 56 bit, which always fit in 64 bit"),
                }
            }
        }
    }

    fn with_offset_prefix_and_add_lead(&self, offset: usize, prefix: u8, lead: SPart) -> VPair {
        // Reserve an additional block in case apply_lead spills over
        let mut v = Vec::with_capacity(self.data.len() + 1 - offset);
        v.push_all(&self.data[offset..]);

        let mut p = VPair {
            data: v,
            prefix: prefix,
            used: self.used,
            leading: self.leading,
        };

        p.apply_lead(lead);

        p
    }

    fn switched_with_new_lead(&self, lead: SPart) -> VPair {
        let mut v = Vec::with_capacity(1);
        v.push(lead.data());

        VPair {
            data: v,
            prefix: 0,
            used: lead.len(),
            leading: self.leading.switched(),
        }
    }

    fn apply_lead(&mut self, mut lead: SPart) {
        let pushable;

        { // make the borrowchecker happy
            let last = self.data.last_mut().unwrap();

            // push all we can into the current byte
            pushable = cmp::min(64 - self.used, lead.len());
            *last |= lead.shift_data(pushable) << self.used;
        }

        if lead.len() == 0 {
            self.used += pushable;
        } else {
            self.data.push(lead.data());
            self.used = lead.len();
        }
    }

    fn head(&self) -> VHead {
        debug_assert!(self.used != 64);

        VHead {
            data: self.data[0],
            prefix: self.prefix,
            used: if self.data.len() > 1 { 64 } else { self.used },
        }
    }

    fn head2(&self) -> VHead {
        debug_assert!(self.data.len() > 1);

        VHead {
            data: self.data[1],
            prefix: 0,
            used: if self.data.len() > 2 { 64 } else { self. used },
        }
    }
}

enum ApplyResult {
    /// No match
    Mismatch,
    /// Completely matched, bits in lead need to be appended
    Match,
    /// Matched but end of block reached, repeat with second block
    MatchRemaining,
    /// Completely caught up, bits in follow make up a new block
    LeadSwitch,
}

impl SPart {
    fn data(&self) -> u64 {
        self.0 & 0x00FF_FFFF_FFFF_FFFF
    }

    fn len(&self) -> u8 {
        (self.0 >> 56) as u8
    }

    fn shift(&mut self, shift: u8) {
        let new_len = self.len() - shift;
        let new_val = self.data() >> shift;
        self.0 = ((new_len as u64) << 56) | new_val;
    }

    fn shift_data(&mut self, shift: u8) -> u64 {
        let data = self.0 & mask(shift);
        self.shift(shift);
        data
    }

    fn shift_prefix(a: &mut SPart, b: &mut SPart) {
        // after the xor the first mismatched bit is a one
        // theres no need for masking data since we need to use the min of the
        // lens and prefix anyway
        let prefix = (a.0 ^ b.0).trailing_zeros() as u8; // 0-64 always fit in an u8
        let prefix = cmp::min(prefix, cmp::min(a.len(), b.len()));
        a.shift(prefix);
        b.shift(prefix);
    }
}

impl VHead {
    fn apply(&mut self, follow: &mut SPart, lead: &mut SPart) -> ApplyResult {
        // fist, check that overlapping follows are equal
        let overlap = cmp::min(self.used - self.prefix, follow.len());

        // check
        let m = mask(overlap);
        let h = (self.data >> self.prefix) & m;
        let p = follow.data() & m;

        if h != p { return Mismatch; }

        // update
        self.prefix += overlap;
        follow.shift(overlap);

        // follow.len() == 0 implies self.prefix == self.used
        // debug_assert!(follow.len() != 0 || self.prefix == self.used)

        if self.prefix == 64 {
            debug_assert!(self.used == 64);
            return MatchRemaining; // Reached the end of block, needs to be removed
        }

        // at this point follow has caught up to lead, so we can eliminate any common prefix from follow and lead
        SPart::shift_prefix(follow, lead);

        match (follow.len() == 0, lead.len() == 0) {
            (_, true) => LeadSwitch, // lead is empty, start a new block with follow
            (false, false) => Mismatch, // both have non matching bits remaining
            (true, false) => Match, // follow is empty
        }
    }
}

/// Create a bitmask of which the lower `cnt` bits are set.
fn mask(cnt: u8) -> u64 {
    (1 << cnt) - 1
}
<|endoftext|>


<commit_before><commit_msg>the beginnings of a to do list<commit_after><|endoftext|>


<commit_before><commit_msg>auto bind<commit_after>fn main() {
    let x = 5;
    println!("{}", x);
}
<|endoftext|>


<commit_before><commit_msg>match<commit_after>fn main() {
    let x = 5;
    match x {
        3|5|6 => { println!("first"); },
        10...16 => { println!("second"); },
        _ => { println!("default");}
    }
}
<|endoftext|>


<commit_before><commit_msg>practice<commit_after>fn main() {}
<|endoftext|>


<commit_before><commit_msg>Added test for util::fisher_shuffle()<commit_after><|endoftext|>


<commit_before><commit_msg>add HashTable::delete<commit_after><|endoftext|>


<commit_before><commit_msg>add mcve for issue 72442<commit_after>// edition:2018

use std::fs::File;
use std::future::Future;
use std::io::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    block_on(async {
        {
            let path = std::path::Path::new(".");
            let mut f = File::open(path.to_str())?;
            //~^ ERROR the trait bound `std::option::Option<&str>: std::convert::AsRef<std::path::Path>` is not satisfied
            let mut src = String::new();
            f.read_to_string(&mut src)?;
            Ok(())
        }
    })
}

fn block_on<F>(f: F) -> F::Output
where
    F: Future<Output = Result<(), Box<dyn std::error::Error>>>,
{
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Fix a bug when fulfilling a promise<commit_after><|endoftext|>