<commit_before>extern crate nannou;

use nannou::{App, Event, Frame, LoopMode, WindowEvent, ElementState};

fn main() {
    nannou::run(model, update, draw);
}

struct Model {
    window: nannou::window::Id,
}

fn model(app: &App) -> Model {
    app.set_loop_mode(LoopMode::wait(3));
    let window = app.new_window().build().unwrap();
    Model { window }
}

fn update(app: &App, model: Model, event: Event) -> Model {
    match event {
        Event::WindowEvent(_id, event) => {
            println!("{:?}", event);
            if let WindowEvent::KeyboardInput { input, .. } = event {
                if let (ElementState::Pressed, Some(_)) = (input.state, input.virtual_keycode) {
                    match app.loop_mode() {
                        LoopMode::Rate { .. } => app.set_loop_mode(LoopMode::wait(3)),
                        LoopMode::Wait { .. } => app.set_loop_mode(LoopMode::rate_fps(60.0)),
                    }
                }
            }
        },
        Event::Update(update) => {
            println!("{:?}", &update);
        },
        _ => (),
    }
    model
}

// Draw the state of your `Model` into the given `Frame` here.
fn draw(_app: &App, model: &Model, frame: Frame) -> Frame {
    frame.window(model.window).unwrap().clear_color(0.1, 0.11, 0.12, 1.0);
    frame
}
<commit_msg>Add some comments to loop_mode.rs example<commit_after>extern crate nannou;

use nannou::{App, Event, Frame, LoopMode, WindowEvent, ElementState};

fn main() {
    nannou::run(model, update, draw);
}

struct Model {
    window: nannou::window::Id,
}

fn model(app: &App) -> Model {
    // Start in `Wait` mode. In other words, don't keep looping, just wait for events.
    app.set_loop_mode(LoopMode::wait(3));
    let window = app.new_window().build().unwrap();
    Model { window }
}

fn update(app: &App, model: Model, event: Event) -> Model {
    match event {
        Event::WindowEvent(_id, event) => {
            println!("{:?}", event);
            // If any key was pressed, switch loop mode.
            if let WindowEvent::KeyboardInput { input, .. } = event {
                if let (ElementState::Pressed, Some(_)) = (input.state, input.virtual_keycode) {
                    match app.loop_mode() {
                        LoopMode::Rate { .. } => app.set_loop_mode(LoopMode::wait(3)),
                        LoopMode::Wait { .. } => app.set_loop_mode(LoopMode::rate_fps(60.0)),
                    }
                }
            }
        },
        Event::Update(update) => {
            println!("{:?}", &update);
        },
        _ => (),
    }
    model
}

// Draw the state of your `Model` into the given `Frame` here.
fn draw(_app: &App, model: &Model, frame: Frame) -> Frame {
    frame.window(model.window).unwrap().clear_color(0.1, 0.11, 0.12, 1.0);
    frame
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::str;

use access::bencode::{BencodeMutKind, BMutAccess, BRefAccess, BencodeRefKind};
use access::dict::BDictAccess;
use access::list::BListAccess;
use mutable::encode;

/// Bencode object that holds references to the underlying data.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum InnerBencodeMut<'a> {
    /// Bencode Integer.
    Int(i64),
    /// Bencode Bytes.
    Bytes(&'a [u8]),
    /// Bencode List.
    List(Vec<BencodeMut<'a>>),
    /// Bencode Dictionary.
    Dict(BTreeMap<&'a [u8], BencodeMut<'a>>),
}

/// `BencodeMut` object that stores references to some data.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct BencodeMut<'a> {
    inner: InnerBencodeMut<'a>
}

impl<'a> BencodeMut<'a> {
    fn new(inner: InnerBencodeMut<'a>) -> BencodeMut<'a> {
        BencodeMut{ inner: inner }
    }

    pub fn new_int(value: i64) -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Int(value))
    }

    pub fn new_bytes(value: &'a [u8]) -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Bytes(value))
    }

    pub fn new_list() -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::List(Vec::new()))
    }

    pub fn new_dict() -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Dict(BTreeMap::new()))
    }

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

        encode::encode(self, &mut buffer);

        buffer
    }
}

impl<'a> BRefAccess<'a> for BencodeMut<'a> {
    type BType = BencodeMut<'a>;

    fn kind<'b>(&'b self) -> BencodeRefKind<'b, 'a, BencodeMut<'a>> {
        match self.inner {
            InnerBencodeMut::Int(n)       => BencodeRefKind::Int(n),
            InnerBencodeMut::Bytes(ref n) => BencodeRefKind::Bytes(n),
            InnerBencodeMut::List(ref n)  => BencodeRefKind::List(n),
            InnerBencodeMut::Dict(ref n)  => BencodeRefKind::Dict(n),
        }
    }

    fn str(&self) -> Option<&'a str> {
        let bytes = match self.bytes() {
            Some(n) => n,
            None => return None,
        };

        match str::from_utf8(bytes) {
            Ok(n) => Some(n),
            Err(_) => None,
        }
    }

    fn int(&self) -> Option<i64> {
        match self.inner {
            InnerBencodeMut::Int(n) => Some(n),
            _ => None,
        }
    }

    fn bytes(&self) -> Option<&'a [u8]> {
        match self.inner {
            InnerBencodeMut::Bytes(ref n) => Some(&n[0..]),
            _ => None,
        }
    }

    fn list(&self) -> Option<&BListAccess<BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::List(ref n) => Some(n),
            _ => None,
        }
    }

    fn dict(&self) -> Option<&BDictAccess<'a, BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::Dict(ref n) => Some(n),
            _ => None,
        }
    }
}

impl<'a> BMutAccess<'a> for BencodeMut<'a> {
    fn kind_mut<'b>(&'b mut self) -> BencodeMutKind<'b, 'a, BencodeMut<'a>> {
        match self.inner {
            InnerBencodeMut::Int(n)           => BencodeMutKind::Int(n),
            InnerBencodeMut::Bytes(ref mut n) => BencodeMutKind::Bytes(n),
            InnerBencodeMut::List(ref mut n)  => BencodeMutKind::List(n),
            InnerBencodeMut::Dict(ref mut n)  => BencodeMutKind::Dict(n),
        }
    }

    fn list_mut(&mut self) -> Option<&mut BListAccess<BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::List(ref mut n) => Some(n),
            _ => None
        }
    }

    fn dict_mut(&mut self) -> Option<&mut BDictAccess<'a, BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::Dict(ref mut n) => Some(n),
            _ => None
        }
    }
}<commit_msg>Update Docs For BencodeMut<commit_after>use std::collections::BTreeMap;
use std::str;

use access::bencode::{BencodeMutKind, BMutAccess, BRefAccess, BencodeRefKind};
use access::dict::BDictAccess;
use access::list::BListAccess;
use mutable::encode;

/// Bencode object that holds references to the underlying data.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum InnerBencodeMut<'a> {
    /// Bencode Integer.
    Int(i64),
    /// Bencode Bytes.
    Bytes(&'a [u8]),
    /// Bencode List.
    List(Vec<BencodeMut<'a>>),
    /// Bencode Dictionary.
    Dict(BTreeMap<&'a [u8], BencodeMut<'a>>),
}

/// `BencodeMut` object that stores references to some data.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub struct BencodeMut<'a> {
    inner: InnerBencodeMut<'a>
}

impl<'a> BencodeMut<'a> {
    fn new(inner: InnerBencodeMut<'a>) -> BencodeMut<'a> {
        BencodeMut{ inner: inner }
    }

    /// Create a new `BencodeMut` representing an `i64`.
    pub fn new_int(value: i64) -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Int(value))
    }

    /// Create a new `BencodeMut` representing a `[u8]`.
    pub fn new_bytes(value: &'a [u8]) -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Bytes(value))
    }

    /// Create a new `BencodeMut` representing a `BListAccess`.
    pub fn new_list() -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::List(Vec::new()))
    }

    /// Create a new `BencodeMut` representing a `BDictAccess`.
    pub fn new_dict() -> BencodeMut<'a> {
        BencodeMut::new(InnerBencodeMut::Dict(BTreeMap::new()))
    }

    /// Encode the `BencodeMut` into a buffer representing the bencode.
    pub fn encode(&self) -> Vec<u8> {
        let mut buffer = Vec::new();

        encode::encode(self, &mut buffer);

        buffer
    }
}

impl<'a> BRefAccess<'a> for BencodeMut<'a> {
    type BType = BencodeMut<'a>;

    fn kind<'b>(&'b self) -> BencodeRefKind<'b, 'a, BencodeMut<'a>> {
        match self.inner {
            InnerBencodeMut::Int(n)       => BencodeRefKind::Int(n),
            InnerBencodeMut::Bytes(ref n) => BencodeRefKind::Bytes(n),
            InnerBencodeMut::List(ref n)  => BencodeRefKind::List(n),
            InnerBencodeMut::Dict(ref n)  => BencodeRefKind::Dict(n),
        }
    }

    fn str(&self) -> Option<&'a str> {
        let bytes = match self.bytes() {
            Some(n) => n,
            None => return None,
        };

        match str::from_utf8(bytes) {
            Ok(n) => Some(n),
            Err(_) => None,
        }
    }

    fn int(&self) -> Option<i64> {
        match self.inner {
            InnerBencodeMut::Int(n) => Some(n),
            _ => None,
        }
    }

    fn bytes(&self) -> Option<&'a [u8]> {
        match self.inner {
            InnerBencodeMut::Bytes(ref n) => Some(&n[0..]),
            _ => None,
        }
    }

    fn list(&self) -> Option<&BListAccess<BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::List(ref n) => Some(n),
            _ => None,
        }
    }

    fn dict(&self) -> Option<&BDictAccess<'a, BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::Dict(ref n) => Some(n),
            _ => None,
        }
    }
}

impl<'a> BMutAccess<'a> for BencodeMut<'a> {
    fn kind_mut<'b>(&'b mut self) -> BencodeMutKind<'b, 'a, BencodeMut<'a>> {
        match self.inner {
            InnerBencodeMut::Int(n)           => BencodeMutKind::Int(n),
            InnerBencodeMut::Bytes(ref mut n) => BencodeMutKind::Bytes(n),
            InnerBencodeMut::List(ref mut n)  => BencodeMutKind::List(n),
            InnerBencodeMut::Dict(ref mut n)  => BencodeMutKind::Dict(n),
        }
    }

    fn list_mut(&mut self) -> Option<&mut BListAccess<BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::List(ref mut n) => Some(n),
            _ => None
        }
    }

    fn dict_mut(&mut self) -> Option<&mut BDictAccess<'a, BencodeMut<'a>>> {
        match self.inner {
            InnerBencodeMut::Dict(ref mut n) => Some(n),
            _ => None
        }
    }
}<|endoftext|>


<commit_before>#![cfg(target_os = "windows")]

use libc;
use MonitorId;
use Window;
use WindowBuilder;
use winapi;

/// Additional methods on `Window` that are specific to Windows.
pub trait WindowExt {
    /// Returns a pointer to the `Window` object of xlib that is used by this window.
    ///
    /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
    ///
    /// The pointer will become invalid when the glutin `Window` is destroyed.
    fn get_hwnd(&self) -> *mut libc::c_void;
}

impl WindowExt for Window {
    #[inline]
    fn get_hwnd(&self) -> *mut libc::c_void {
        self.window.hwnd() as *mut _
    }
}

/// Additional methods on `WindowBuilder` that are specific to Windows.
pub trait WindowBuilderExt {
    fn with_parent_window(self, parent: winapi::HWND) -> WindowBuilder;
}

impl WindowBuilderExt for WindowBuilder {
    /// Sets a parent to the window to be created
    #[inline]
    fn with_parent_window(mut self, parent: winapi::HWND) -> WindowBuilder {
        self.platform_specific.parent = Some(parent);
        self
    }
}

/// Additional methods on `MonitorId` that are specific to Windows.
pub trait MonitorIdExt {
    /// Returns the name of the monitor specific to the Win32 API.
    fn native_id(&self) -> String;
}

impl MonitorIdExt for MonitorId {
    #[inline]
    fn native_id(&self) -> String {
        self.inner.get_native_identifier()
    }
}
<commit_msg>Update docs of windows-specific methods (#281)<commit_after>#![cfg(target_os = "windows")]

use libc;
use MonitorId;
use Window;
use WindowBuilder;
use winapi;

/// Additional methods on `Window` that are specific to Windows.
pub trait WindowExt {
    /// Returns the native handle that is used by this window.
    ///
    /// The pointer will become invalid when the native window was destroyed.
    fn get_hwnd(&self) -> *mut libc::c_void;
}

impl WindowExt for Window {
    #[inline]
    fn get_hwnd(&self) -> *mut libc::c_void {
        self.window.hwnd() as *mut _
    }
}

/// Additional methods on `WindowBuilder` that are specific to Windows.
pub trait WindowBuilderExt {
    fn with_parent_window(self, parent: winapi::HWND) -> WindowBuilder;
}

impl WindowBuilderExt for WindowBuilder {
    /// Sets a parent to the window to be created.
    #[inline]
    fn with_parent_window(mut self, parent: winapi::HWND) -> WindowBuilder {
        self.platform_specific.parent = Some(parent);
        self
    }
}

/// Additional methods on `MonitorId` that are specific to Windows.
pub trait MonitorIdExt {
    /// Returns the name of the monitor specific to the Win32 API.
    fn native_id(&self) -> String;
}

impl MonitorIdExt for MonitorId {
    #[inline]
    fn native_id(&self) -> String {
        self.inner.get_native_identifier()
    }
}
<|endoftext|>


<commit_before>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
//
// TODO: Implement custom subtyping here for things like GParamSpecInt to get
// default/min/max values and similar
#[cfg(any(feature = "v2_38", feature = "dox"))]
use Value;
use gobject_ffi as ffi;
use ffi as glib_ffi;
use gobject_ffi;
use std::mem;
use std::ptr;
use libc;
use translate::*;
use ParamFlags;

glib_wrapper! {
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct ParamSpec(Shared<ffi::GParamSpec>);

    match fn {
        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr),
        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr),
        get_type => || gobject_ffi::G_TYPE_PARAM,
    }
}

unsafe impl Send for ParamSpec {}
unsafe impl Sync for ParamSpec {}

impl ParamSpec {
    pub fn get_value_type(&self) -> ::Type {
        unsafe {
            from_glib((*self.to_glib_none().0).value_type)
        }
    }

    pub fn get_owner_type(&self) -> ::Type {
        unsafe {
            from_glib((*self.to_glib_none().0).owner_type)
        }
    }

    pub fn get_flags(&self) -> ParamFlags {
        unsafe {
            from_glib((*self.to_glib_none().0).flags)
        }
    }

    pub fn get_blurb(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_blurb(self.to_glib_none().0))
        }
    }

    #[cfg(any(feature = "v2_38", feature = "dox"))]
    pub fn get_default_value(&self) -> Option<Value> {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_default_value(self.to_glib_none().0))
        }
    }

    pub fn get_name(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_name(self.to_glib_none().0))
        }
    }

    #[cfg(any(feature = "v2_46", feature = "dox"))]
    pub fn get_name_quark(&self) -> ::Quark {
        unsafe { from_glib(ffi::g_param_spec_get_name_quark(self.to_glib_none().0)) }
    }

    pub fn get_nick(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_nick(self.to_glib_none().0))
        }
    }

    //pub fn get_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
    //    unsafe { TODO: call ffi::g_param_spec_get_qdata() }
    //}

    pub fn get_redirect_target(&self) -> Option<ParamSpec> {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_redirect_target(self.to_glib_none().0))
        }
    }

    //pub fn set_qdata<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, quark: /*Ignored*/glib::Quark, data: P) {
    //    unsafe { TODO: call ffi::g_param_spec_set_qdata() }
    //}

    //pub fn set_qdata_full<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, quark: /*Ignored*/glib::Quark, data: P, destroy: /*Unknown conversion*//*Unimplemented*/DestroyNotify) {
    //    unsafe { TODO: call ffi::g_param_spec_set_qdata_full() }
    //}

    //pub fn steal_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
    //    unsafe { TODO: call ffi::g_param_spec_steal_qdata() }
    //}

    pub fn boolean(name: &str, nick: &str, blurb: &str, default_value: bool, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_boolean(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.to_glib(), flags.to_glib()))
        }
    }

    pub fn boxed(name: &str, nick: &str, blurb: &str, boxed_type: ::Type, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_boxed(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, boxed_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn char(name: &str, nick: &str, blurb: &str, minimum: i8, maximum: i8, default_value: i8, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_char(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn double(name: &str, nick: &str, blurb: &str, minimum: f64, maximum: f64, default_value: f64, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_double(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn enum_(name: &str, nick: &str, blurb: &str, enum_type: ::Type, default_value: i32, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_enum(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, enum_type.to_glib(), default_value, flags.to_glib()))
        }
    }

    pub fn flags(name: &str, nick: &str, blurb: &str, flags_type: ::Type, default_value: u32, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_flags(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, flags_type.to_glib(), default_value, flags.to_glib()))
        }
    }

    pub fn float(name: &str, nick: &str, blurb: &str, minimum: f32, maximum: f32, default_value: f32, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_float(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn gtype(name: &str, nick: &str, blurb: &str, is_a_type: ::Type, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_gtype(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, is_a_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn int(name: &str, nick: &str, blurb: &str, minimum: i32, maximum: i32, default_value: i32, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_int(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn int64(name: &str, nick: &str, blurb: &str, minimum: i64, maximum: i64, default_value: i64, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_int64(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn long(name: &str, nick: &str, blurb: &str, minimum: libc::c_long, maximum: libc::c_long, default_value: libc::c_long, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_long(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn object(name: &str, nick: &str, blurb: &str, object_type: ::Type, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_object(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, object_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn override_(name: &str, overridden: &ParamSpec) -> Option<ParamSpec> {
        unsafe {
            from_glib_none(ffi::g_param_spec_override(name.to_glib_none().0, overridden.to_glib_none().0))
        }
    }

    pub fn param(name: &str, nick: &str, blurb: &str, param_type: ::Type, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_param(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, param_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn pointer(name: &str, nick: &str, blurb: &str, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_pointer(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, flags.to_glib()))
        }
    }

    pub fn string<'a, P: Into<Option<&'a str>>>(name: &str, nick: &str, blurb: &str, default_value: P, flags: ParamFlags) -> Option<ParamSpec> {
        let default_value = default_value.into();
        let default_value = default_value.to_glib_none();
        unsafe {
            from_glib_full(ffi::g_param_spec_string(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.0, flags.to_glib()))
        }
    }

    pub fn uchar(name: &str, nick: &str, blurb: &str, minimum: u8, maximum: u8, default_value: u8, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_uchar(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn uint(name: &str, nick: &str, blurb: &str, minimum: u32, maximum: u32, default_value: u32, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_uint(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn uint64(name: &str, nick: &str, blurb: &str, minimum: u64, maximum: u64, default_value: u64, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_uint64(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn ulong(name: &str, nick: &str, blurb: &str, minimum: libc::c_ulong, maximum: libc::c_ulong, default_value: libc::c_ulong, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_ulong(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn unichar(name: &str, nick: &str, blurb: &str, default_value: char, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_full(ffi::g_param_spec_unichar(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.to_glib(), flags.to_glib()))
        }
    }

    pub fn value_array(name: &str, nick: &str, blurb: &str, element_spec: &ParamSpec, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            from_glib_none(ffi::g_param_spec_value_array(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, element_spec.to_glib_none().0, flags.to_glib()))
        }
    }

    pub fn variant<'a, P: Into<Option<&'a ::Variant>>>(name: &str, nick: &str, blurb: &str, type_: &::VariantTy, default_value: P, flags: ParamFlags) -> Option<ParamSpec> {
        unsafe {
            let default_value = default_value.into();
            from_glib_none(ffi::g_param_spec_variant(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, type_.to_glib_none().0, default_value.to_glib_none().0, flags.to_glib()))
        }
    }
}
<commit_msg>ParamSpec constructors can't return NULL<commit_after>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
//
// TODO: Implement custom subtyping here for things like GParamSpecInt to get
// default/min/max values and similar
#[cfg(any(feature = "v2_38", feature = "dox"))]
use Value;
use gobject_ffi as ffi;
use ffi as glib_ffi;
use gobject_ffi;
use std::mem;
use std::ptr;
use libc;
use translate::*;
use ParamFlags;

glib_wrapper! {
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct ParamSpec(Shared<ffi::GParamSpec>);

    match fn {
        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr),
        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr),
        get_type => || gobject_ffi::G_TYPE_PARAM,
    }
}

unsafe impl Send for ParamSpec {}
unsafe impl Sync for ParamSpec {}

impl ParamSpec {
    pub fn get_value_type(&self) -> ::Type {
        unsafe {
            from_glib((*self.to_glib_none().0).value_type)
        }
    }

    pub fn get_owner_type(&self) -> ::Type {
        unsafe {
            from_glib((*self.to_glib_none().0).owner_type)
        }
    }

    pub fn get_flags(&self) -> ParamFlags {
        unsafe {
            from_glib((*self.to_glib_none().0).flags)
        }
    }

    pub fn get_blurb(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_blurb(self.to_glib_none().0))
        }
    }

    #[cfg(any(feature = "v2_38", feature = "dox"))]
    pub fn get_default_value(&self) -> Option<Value> {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_default_value(self.to_glib_none().0))
        }
    }

    pub fn get_name(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_name(self.to_glib_none().0))
        }
    }

    #[cfg(any(feature = "v2_46", feature = "dox"))]
    pub fn get_name_quark(&self) -> ::Quark {
        unsafe { from_glib(ffi::g_param_spec_get_name_quark(self.to_glib_none().0)) }
    }

    pub fn get_nick(&self) -> String {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_nick(self.to_glib_none().0))
        }
    }

    //pub fn get_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
    //    unsafe { TODO: call ffi::g_param_spec_get_qdata() }
    //}

    pub fn get_redirect_target(&self) -> Option<ParamSpec> {
        unsafe {
            from_glib_none(ffi::g_param_spec_get_redirect_target(self.to_glib_none().0))
        }
    }

    //pub fn set_qdata<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, quark: /*Ignored*/glib::Quark, data: P) {
    //    unsafe { TODO: call ffi::g_param_spec_set_qdata() }
    //}

    //pub fn set_qdata_full<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, quark: /*Ignored*/glib::Quark, data: P, destroy: /*Unknown conversion*//*Unimplemented*/DestroyNotify) {
    //    unsafe { TODO: call ffi::g_param_spec_set_qdata_full() }
    //}

    //pub fn steal_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> {
    //    unsafe { TODO: call ffi::g_param_spec_steal_qdata() }
    //}

    pub fn boolean(name: &str, nick: &str, blurb: &str, default_value: bool, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_boolean(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.to_glib(), flags.to_glib()))
        }
    }

    pub fn boxed(name: &str, nick: &str, blurb: &str, boxed_type: ::Type, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_boxed(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, boxed_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn char(name: &str, nick: &str, blurb: &str, minimum: i8, maximum: i8, default_value: i8, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_char(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn double(name: &str, nick: &str, blurb: &str, minimum: f64, maximum: f64, default_value: f64, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_double(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn enum_(name: &str, nick: &str, blurb: &str, enum_type: ::Type, default_value: i32, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_enum(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, enum_type.to_glib(), default_value, flags.to_glib()))
        }
    }

    pub fn flags(name: &str, nick: &str, blurb: &str, flags_type: ::Type, default_value: u32, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_flags(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, flags_type.to_glib(), default_value, flags.to_glib()))
        }
    }

    pub fn float(name: &str, nick: &str, blurb: &str, minimum: f32, maximum: f32, default_value: f32, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_float(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn gtype(name: &str, nick: &str, blurb: &str, is_a_type: ::Type, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_gtype(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, is_a_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn int(name: &str, nick: &str, blurb: &str, minimum: i32, maximum: i32, default_value: i32, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_int(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn int64(name: &str, nick: &str, blurb: &str, minimum: i64, maximum: i64, default_value: i64, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_int64(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn long(name: &str, nick: &str, blurb: &str, minimum: libc::c_long, maximum: libc::c_long, default_value: libc::c_long, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_long(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn object(name: &str, nick: &str, blurb: &str, object_type: ::Type, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_object(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, object_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn override_(name: &str, overridden: &ParamSpec) -> ParamSpec {
        unsafe {
            from_glib_none(ffi::g_param_spec_override(name.to_glib_none().0, overridden.to_glib_none().0))
        }
    }

    pub fn param(name: &str, nick: &str, blurb: &str, param_type: ::Type, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_param(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, param_type.to_glib(), flags.to_glib()))
        }
    }

    pub fn pointer(name: &str, nick: &str, blurb: &str, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_pointer(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, flags.to_glib()))
        }
    }

    pub fn string<'a, P: Into<Option<&'a str>>>(name: &str, nick: &str, blurb: &str, default_value: P, flags: ParamFlags) -> ParamSpec {
        let default_value = default_value.into();
        let default_value = default_value.to_glib_none();
        unsafe {
            from_glib_full(ffi::g_param_spec_string(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.0, flags.to_glib()))
        }
    }

    pub fn uchar(name: &str, nick: &str, blurb: &str, minimum: u8, maximum: u8, default_value: u8, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_uchar(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn uint(name: &str, nick: &str, blurb: &str, minimum: u32, maximum: u32, default_value: u32, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_uint(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn uint64(name: &str, nick: &str, blurb: &str, minimum: u64, maximum: u64, default_value: u64, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_uint64(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn ulong(name: &str, nick: &str, blurb: &str, minimum: libc::c_ulong, maximum: libc::c_ulong, default_value: libc::c_ulong, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_ulong(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, minimum, maximum, default_value, flags.to_glib()))
        }
    }

    pub fn unichar(name: &str, nick: &str, blurb: &str, default_value: char, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_full(ffi::g_param_spec_unichar(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, default_value.to_glib(), flags.to_glib()))
        }
    }

    pub fn value_array(name: &str, nick: &str, blurb: &str, element_spec: &ParamSpec, flags: ParamFlags) -> ParamSpec {
        unsafe {
            from_glib_none(ffi::g_param_spec_value_array(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, element_spec.to_glib_none().0, flags.to_glib()))
        }
    }

    pub fn variant<'a, P: Into<Option<&'a ::Variant>>>(name: &str, nick: &str, blurb: &str, type_: &::VariantTy, default_value: P, flags: ParamFlags) -> ParamSpec {
        unsafe {
            let default_value = default_value.into();
            from_glib_none(ffi::g_param_spec_variant(name.to_glib_none().0, nick.to_glib_none().0, blurb.to_glib_none().0, type_.to_glib_none().0, default_value.to_glib_none().0, flags.to_glib()))
        }
    }
}
<|endoftext|>


<commit_before>extern crate tempfile;

use std::fmt::{ Display, Formatter, Error };
use std::iter::Iterator;
use std::collections::HashMap;
use std::collections::HashSet;
use std::vec::Vec;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

use std::clone::Clone;

/// Get the (arbitrary) zeroth element of a hashset.
#[marco_export]
macro_rules! zeroth {
    ($hs: expr) => {{
        *$hs.iter().next().unwrap()
    }}
}

/**
 * test can be deleted.
 * clauses will house all clauses, key is int so that we can use occurrences
 * ID for simplifications later
 * occurrences tracks which clauses literals are used in
 */
#[derive(Debug)]
pub struct CNF {
    pub nvar        : i32,
    pub nclause     : i32,
    pub clauses     : HashMap<i32, HashSet<i32>>,
    pub occurrences : HashMap<i32, Vec<i32>>,
    pub units       : HashSet<i32>
}

impl CNF {
    pub fn new(nvar: i32, nclause: i32) -> CNF {
        CNF {
            nvar        : nvar,
            nclause     : nclause,
            clauses     : HashMap::new(),
            occurrences : HashMap::new(),
            units       : HashSet::new(),
        }
    }

    /// Add a clause, return the ID of the inserted clause
    /// Right now, this isn't public; api is odd as we have an odd representation of literals.
    /// TODO: Mask this with public function?
    fn add_clause(&mut self, clause: HashSet<i32>) -> i32 {
        assert!(clause.len() > 0);
        let id: i32 = self.clauses.len() as i32;
        if clause.len() == 1 { self.units.insert(id); }
        for var in &clause {
            let occ = self.occurrences.entry(*var).or_insert(Vec::new());
            occ.push(id);
        }
        self.clauses.insert(id, clause);
        id
    }

    /// Unit propagation: propagate the literal associated with the clause id `clause`, and remove
    /// it from `self.units`.
    pub fn unit_propagate(&mut self, unit: i32) {
		println!("UNIT_PROP {}",unit);
        // Remove clauses with lit and remove lit from occurrences.
        let lit = zeroth!(self.clauses.get(&unit).expect("unit clause not found"));
        self.propagate(lit);
        // This needs to be true, i.e. unit clause id needs to be in the unit clauses
        assert!(self.units.remove(&unit));
    }

    /// Remove all clauses containing literal `lit` from the CNF, and remove the negation of `lit`
    /// from the remaining clauses.
    /// TODO: unit_propagate and propagate should return true/false
    /// depending on whether the updated CNF problem is satisfiable
    pub fn propagate(&mut self, lit: i32) {
		// Remove clauses with lit and remove lit from occurrences.
		if let Some(vec) = self.occurrences.remove(&lit) {
			for occ in &vec {
				self.clauses.remove(occ);
				self.nclause-=1;
			}
		}

        // Remove ~lit from other clausesa
		self.remove_negation(lit);
    }

	fn remove_negation(&mut self, lit : i32){
		let neg = lit^1;
		if let Some(vec) = self.occurrences.remove(&neg) {
			for occ in &vec {
				if let Some(mut c) = self.clauses.remove(occ) {
					c.remove(&neg);
					self.clauses.insert(*occ, c);
				}
			}
		}
	}
}

impl Clone for CNF {
    fn clone(&self) -> CNF {
        CNF {
            nvar        : self.nvar,
            nclause     : self.nclause,
            clauses     : self.clauses.clone(),
            occurrences : self.occurrences.clone(),
            units       : self.units.clone()
        }
    }
}

impl Display for CNF {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let formatted = format!("Nvar: {:?} Nclause: {:?} Units: {:?}\nClauses: {:?}\nOccurrrences: {:?}",
                self.nvar, self.nclause, self.units,
                self.clauses, self.occurrences);
        write!(f, "{}", formatted)
    }
}

// End CNF

// Begin Assignemnts

pub type Assignment = Vec<bool>;

pub struct PartialAssignment {
    pub assignment : Vec<Option<bool>>,
    pub unassigned : HashSet<i32>
}

impl PartialAssignment {
    pub fn new(n: usize) -> PartialAssignment {
        PartialAssignment {
            assignment : vec!(None; n),
            unassigned : (0..n as i32).collect()
        }
    }

    fn assign(&mut self, v: usize, assn: bool) {
        // TODO: Error check
        self.assignment[v] = Some(assn);
		self.unassigned.remove(&(v as i32));
    }

    pub fn assign_literal(&mut self, lit: i32){
        let polarity: bool = lit & 1 == 0;
        let v: usize = (lit >> 1) as usize;
        self.assign(v - 1, polarity);
    }

    fn unassign(&mut self, v: usize) {
        self.assignment[v] = None;
		self.unassigned.insert(v as i32);
    }

    pub fn unassign_literal(&mut self, lit: i32){
        let v: usize = (lit >> 1) as usize;
        self.unassign(v - 1);
    }
}

impl Clone for PartialAssignment {
    fn clone(&self) -> PartialAssignment {
		PartialAssignment {
            assignment : self.assignment.clone(),
            unassigned : self.unassigned.clone(),
        }
    }
}

// TODO: Implement Display
impl Display for PartialAssignment {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let formatted = format!("Assignemnts: {:?}\nUnassigned: {:?}",
                self.assignment, self.unassigned);
        write!(f, "{}", formatted)
    }
}

// End Assignments

// Begin Parsing

// TODO: rename to from_dimacs or somehow isolate parsing
fn parse_dimacs(reader: &mut BufReader<File>) -> Result<CNF, &'static str> {
    let mut line_iterator = reader.lines();

    let mut nvar: i32 = -1;
    let mut nclause: i32 = -1;
    // DIMACS file must have a problem statement before other lines.
    // This first loop searches for the problem statement.
    for line in &mut line_iterator {
        let line = line.expect("could not read file");  // Unwrap result
        let words: Vec<&str> = line.split_whitespace().collect();
        if words.len() == 0 { continue; } // Ignore empty lines
        match words[0] {
            "c" => { }
            "p" => { // Problem statement
                // Must have format "p cnf nvar nclause"
                if words.len() != 4 || words[1] != "cnf" {
                    return Err("invalid problem statement");
                }
                nvar = words[2].parse()
                    .expect(&format!("invalid number of variables {}", words[2]));
                nclause = words[3].parse()
                    .expect(&format!("invalid number of clauses {}", words[3]));
                break;
            }
            // TODO: Add words[0] to this error message
            _ => { return Err("unknown statement beginning"); }
        }
    }
    // Then nvar, nclause were never initialized
    if nvar == -1 || nclause == -1 {
       return Err("no problem statement found");
    }
    // TODO: Different errors for different descriptions (hence why I've split up this if
    // statement)
    if nvar == 0 || nclause == 0 {
        return Err("invalid number of literals in problem")
    }

    // Initialize CNF and parse the rest of the file
    let mut cnf = CNF::new(nvar, nclause);
    let mut clauses_read: i32 = 0;
    for line in &mut line_iterator {
        let line = line.unwrap();
        let words: Vec<&str> = line.split_whitespace().collect();
        if words.len() == 0 { continue; }
        match words[0] {
            "c" => { }
            "p" => { return Err("duplicate problem statement"); }
            _   => {
                clauses_read = clauses_read + 1;
                if clauses_read > nclause { return Err("too many clauses in file"); }
                let tokens: HashSet<i32> = words.iter()
                    .filter_map(|s| {
                        let n = s.parse::<i32>().unwrap();
                        // FIXME: This ignores zeros not just as line enders but in the formulas
                        // themselves. Split on zeros at the end here.
                        if n == 0 { return None; }
                        // FIXME: This should return an error instead of
                        // panicking, but I can't return an error
                        // in a closure
                        if n > nvar { panic!("variable out of range: {}", n); }
                        Some(if n < 0 { (-n) << 1 | 1 } else { n << 1 })
                    })
                    .collect();
                cnf.add_clause(tokens);
            }
        }
    }
    // Double check that the number of clauses read is equal
    if clauses_read != nclause { return Err("too few clauses in file"); }
    Ok(cnf)
}

pub fn parse_dimacs_file(f: File) -> Result<CNF, &'static str> {
    // Read the file
    let mut reader = BufReader::new(f);

    // TODO: This is definitely not the correct way to handle errors.
    // Should parse_dimacs have options for returning an error AND panicking?
    let line = parse_dimacs(&mut reader);
    line
}

#[cfg(test)]
mod tests {
    extern crate tempfile;
    use std::fs::File;
    use std::io::prelude::*;
    use std::io::SeekFrom;
    use std::collections::HashSet;

    use super::parse_dimacs_file;
    // use super::zeroth;

    macro_rules! create_tempfile {
        ($x: expr) => {{
            let mut tmpfile: File = tempfile::tempfile().unwrap();
            let _ = write!(tmpfile, $x);
            tmpfile.seek(SeekFrom::Start(0)).unwrap();

            tmpfile
        }};
    }

    #[test]
    #[should_panic(expected = "out of range")]
    fn variable_out_of_range() {
        let tmpfile = create_tempfile!("
            p cnf 2 3
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "invalid number")]
    fn invalid_nvar() {
        let tmpfile = create_tempfile!("
            p cnf gd 3
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "invalid number")]
    fn invalid_nclause() {
        let tmpfile = create_tempfile!("
            p cnf 2 gdd
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "too many")]
    fn too_many_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 5 5
            1 2 0
            2 3 0
            3 4 0
            4 5 0
            1 3 0
            2 4 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "too few")]
    fn too_little_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 5 5
            1 2 0
            2 3 0
            3 4 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn should_work() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            1 2 0
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn should_ignore_comments() {
        let tmpfile = create_tempfile!("
            c comment
            p cnf 3 3
            c comment
            1 2 0
            2 3 0
            c comment
            1 -3 0
            c comment
            c comment
            c comment
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "duplicate problem")]
    fn duplicate_problem_statement() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            1 2 0
            p cnf 3 3
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "duplicate problem")]
    fn duplicate_problem_statement_2() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            p cnf 3 3
            1 2 0
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn adds_unit_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 3 4
            1 0
            2 0
            3 0
            -1 -3 0
        ");
        let cnf = parse_dimacs_file(tmpfile).unwrap();
        assert_eq!(cnf.units.len(), 3);
    }

    // TODO: Make this doc test (with unit propagate); create_tempfile may need to be an importable
    // macro up there
    #[test]
    fn unit_propagate_works() {
        let tmpfile = create_tempfile!("
            p cnf 2 2
            1 0
            1 2 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(0);
        assert!(cnf.units.is_empty());
    }

    #[test]
    fn unit_propagate_works_2() {
        let tmpfile = create_tempfile!("
            p cnf 4 4
            1 0
            1 2 0
            2 3 0
            4 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(0);
        // Only one unit clause left
        assert_eq!(cnf.units.len(), 1);
        cnf.unit_propagate(3);
        // No more unit clauses
        assert!(cnf.units.is_empty());
    }

    #[test]
    #[should_panic(expected = "unit clause not found")]
    fn unit_clause_not_found() {
        let tmpfile = create_tempfile!("
            p cnf 2 2
            1 0
            1 2 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(2);
    }

    #[test]
    fn zeroth_works() {
        let mut hs = HashSet::new();
        hs.insert(5);
        assert_eq!(zeroth!(hs), 5);
    }

    #[test]
    fn zeroth_works_2() {
        let mut hs = HashSet::new();
        hs.insert(5);
        hs.insert(535);
        let zth = zeroth!(hs);
        assert!(zth == 5 || zth == 535);
    }
}
<commit_msg>Add unit clauses on propogate<commit_after>extern crate tempfile;

use std::fmt::{ Display, Formatter, Error };
use std::iter::Iterator;
use std::collections::HashMap;
use std::collections::HashSet;
use std::vec::Vec;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

use std::clone::Clone;

/// Get the (arbitrary) zeroth element of a hashset.
#[marco_export]
macro_rules! zeroth {
    ($hs: expr) => {{
        *$hs.iter().next().unwrap()
    }}
}

/**
 * test can be deleted.
 * clauses will house all clauses, key is int so that we can use occurrences
 * ID for simplifications later
 * occurrences tracks which clauses literals are used in
 */
#[derive(Debug)]
pub struct CNF {
    pub nvar        : i32,
    pub nclause     : i32,
    pub clauses     : HashMap<i32, HashSet<i32>>,
    pub occurrences : HashMap<i32, Vec<i32>>,
    pub units       : HashSet<i32>
}

impl CNF {
    pub fn new(nvar: i32, nclause: i32) -> CNF {
        CNF {
            nvar        : nvar,
            nclause     : nclause,
            clauses     : HashMap::new(),
            occurrences : HashMap::new(),
            units       : HashSet::new(),
        }
    }

    /// Add a clause, return the ID of the inserted clause
    /// Right now, this isn't public; api is odd as we have an odd representation of literals.
    /// TODO: Mask this with public function?
    fn add_clause(&mut self, clause: HashSet<i32>) -> i32 {
        assert!(clause.len() > 0);
        let id: i32 = self.clauses.len() as i32;
        if clause.len() == 1 { self.units.insert(id); }
        for var in &clause {
            let occ = self.occurrences.entry(*var).or_insert(Vec::new());
            occ.push(id);
        }
        self.clauses.insert(id, clause);
        id
    }

    /// Unit propagation: propagate the literal associated with the clause id `clause`, and remove
    /// it from `self.units`.
    pub fn unit_propagate(&mut self, unit: i32) {
		println!("UNIT_PROP {}",unit);
        // Remove clauses with lit and remove lit from occurrences.
        let lit = zeroth!(self.clauses.get(&unit).expect("unit clause not found"));
        self.propagate(lit);
        // This needs to be true, i.e. unit clause id needs to be in the unit clauses
        assert!(self.units.remove(&unit));
    }

    /// Remove all clauses containing literal `lit` from the CNF, and remove the negation of `lit`
    /// from the remaining clauses.
    /// TODO: unit_propagate and propagate should return true/false
    /// depending on whether the updated CNF problem is satisfiable
    pub fn propagate(&mut self, lit: i32) {
		// Remove clauses with lit and remove lit from occurrences.
		if let Some(vec) = self.occurrences.remove(&lit) {
			for occ in &vec {
				self.clauses.remove(occ);
				self.nclause-=1;
			}
		}

        // Remove ~lit from other clausesa
		self.remove_negation(lit);
    }

	fn remove_negation(&mut self, lit : i32){
		let neg = lit^1;
		if let Some(vec) = self.occurrences.remove(&neg) {
			for occ in &vec {
				if let Some(mut c) = self.clauses.remove(occ) {
					c.remove(&neg);
					if c.len()==1 { self.units.insert(*occ); }
					self.clauses.insert(*occ, c);
				}
			}
		}
	}
}

impl Clone for CNF {
    fn clone(&self) -> CNF {
        CNF {
            nvar        : self.nvar,
            nclause     : self.nclause,
            clauses     : self.clauses.clone(),
            occurrences : self.occurrences.clone(),
            units       : self.units.clone()
        }
    }
}

impl Display for CNF {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let formatted = format!("Nvar: {:?} Nclause: {:?} Units: {:?}\nClauses: {:?}\nOccurrrences: {:?}",
                self.nvar, self.nclause, self.units,
                self.clauses, self.occurrences);
        write!(f, "{}", formatted)
    }
}

// End CNF

// Begin Assignemnts

pub type Assignment = Vec<bool>;

pub struct PartialAssignment {
    pub assignment : Vec<Option<bool>>,
    pub unassigned : HashSet<i32>
}

impl PartialAssignment {
    pub fn new(n: usize) -> PartialAssignment {
        PartialAssignment {
            assignment : vec!(None; n),
            unassigned : (0..n as i32).collect()
        }
    }

    fn assign(&mut self, v: usize, assn: bool) {
        // TODO: Error check
        self.assignment[v] = Some(assn);
		self.unassigned.remove(&(v as i32));
    }

    pub fn assign_literal(&mut self, lit: i32){
        let polarity: bool = lit & 1 == 0;
        let v: usize = (lit >> 1) as usize;
        self.assign(v - 1, polarity);
    }

    fn unassign(&mut self, v: usize) {
        self.assignment[v] = None;
		self.unassigned.insert(v as i32);
    }

    pub fn unassign_literal(&mut self, lit: i32){
        let v: usize = (lit >> 1) as usize;
        self.unassign(v - 1);
    }
}

impl Clone for PartialAssignment {
    fn clone(&self) -> PartialAssignment {
		PartialAssignment {
            assignment : self.assignment.clone(),
            unassigned : self.unassigned.clone(),
        }
    }
}

// TODO: Implement Display
impl Display for PartialAssignment {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let formatted = format!("Assignemnts: {:?}\nUnassigned: {:?}",
                self.assignment, self.unassigned);
        write!(f, "{}", formatted)
    }
}

// End Assignments

// Begin Parsing

// TODO: rename to from_dimacs or somehow isolate parsing
fn parse_dimacs(reader: &mut BufReader<File>) -> Result<CNF, &'static str> {
    let mut line_iterator = reader.lines();

    let mut nvar: i32 = -1;
    let mut nclause: i32 = -1;
    // DIMACS file must have a problem statement before other lines.
    // This first loop searches for the problem statement.
    for line in &mut line_iterator {
        let line = line.expect("could not read file");  // Unwrap result
        let words: Vec<&str> = line.split_whitespace().collect();
        if words.len() == 0 { continue; } // Ignore empty lines
        match words[0] {
            "c" => { }
            "p" => { // Problem statement
                // Must have format "p cnf nvar nclause"
                if words.len() != 4 || words[1] != "cnf" {
                    return Err("invalid problem statement");
                }
                nvar = words[2].parse()
                    .expect(&format!("invalid number of variables {}", words[2]));
                nclause = words[3].parse()
                    .expect(&format!("invalid number of clauses {}", words[3]));
                break;
            }
            // TODO: Add words[0] to this error message
            _ => { return Err("unknown statement beginning"); }
        }
    }
    // Then nvar, nclause were never initialized
    if nvar == -1 || nclause == -1 {
       return Err("no problem statement found");
    }
    // TODO: Different errors for different descriptions (hence why I've split up this if
    // statement)
    if nvar == 0 || nclause == 0 {
        return Err("invalid number of literals in problem")
    }

    // Initialize CNF and parse the rest of the file
    let mut cnf = CNF::new(nvar, nclause);
    let mut clauses_read: i32 = 0;
    for line in &mut line_iterator {
        let line = line.unwrap();
        let words: Vec<&str> = line.split_whitespace().collect();
        if words.len() == 0 { continue; }
        match words[0] {
            "c" => { }
            "p" => { return Err("duplicate problem statement"); }
            _   => {
                clauses_read = clauses_read + 1;
                if clauses_read > nclause { return Err("too many clauses in file"); }
                let tokens: HashSet<i32> = words.iter()
                    .filter_map(|s| {
                        let n = s.parse::<i32>().unwrap();
                        // FIXME: This ignores zeros not just as line enders but in the formulas
                        // themselves. Split on zeros at the end here.
                        if n == 0 { return None; }
                        // FIXME: This should return an error instead of
                        // panicking, but I can't return an error
                        // in a closure
                        if n > nvar { panic!("variable out of range: {}", n); }
                        Some(if n < 0 { (-n) << 1 | 1 } else { n << 1 })
                    })
                    .collect();
                cnf.add_clause(tokens);
            }
        }
    }
    // Double check that the number of clauses read is equal
    if clauses_read != nclause { return Err("too few clauses in file"); }
    Ok(cnf)
}

pub fn parse_dimacs_file(f: File) -> Result<CNF, &'static str> {
    // Read the file
    let mut reader = BufReader::new(f);

    // TODO: This is definitely not the correct way to handle errors.
    // Should parse_dimacs have options for returning an error AND panicking?
    let line = parse_dimacs(&mut reader);
    line
}

#[cfg(test)]
mod tests {
    extern crate tempfile;
    use std::fs::File;
    use std::io::prelude::*;
    use std::io::SeekFrom;
    use std::collections::HashSet;

    use super::parse_dimacs_file;
    // use super::zeroth;

    macro_rules! create_tempfile {
        ($x: expr) => {{
            let mut tmpfile: File = tempfile::tempfile().unwrap();
            let _ = write!(tmpfile, $x);
            tmpfile.seek(SeekFrom::Start(0)).unwrap();

            tmpfile
        }};
    }

    #[test]
    #[should_panic(expected = "out of range")]
    fn variable_out_of_range() {
        let tmpfile = create_tempfile!("
            p cnf 2 3
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "invalid number")]
    fn invalid_nvar() {
        let tmpfile = create_tempfile!("
            p cnf gd 3
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "invalid number")]
    fn invalid_nclause() {
        let tmpfile = create_tempfile!("
            p cnf 2 gdd
            1 2 0
            4 1 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "too many")]
    fn too_many_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 5 5
            1 2 0
            2 3 0
            3 4 0
            4 5 0
            1 3 0
            2 4 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "too few")]
    fn too_little_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 5 5
            1 2 0
            2 3 0
            3 4 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn should_work() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            1 2 0
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn should_ignore_comments() {
        let tmpfile = create_tempfile!("
            c comment
            p cnf 3 3
            c comment
            1 2 0
            2 3 0
            c comment
            1 -3 0
            c comment
            c comment
            c comment
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "duplicate problem")]
    fn duplicate_problem_statement() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            1 2 0
            p cnf 3 3
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    #[should_panic(expected = "duplicate problem")]
    fn duplicate_problem_statement_2() {
        let tmpfile = create_tempfile!("
            p cnf 3 3
            p cnf 3 3
            1 2 0
            2 3 0
            1 -3 0
        ");
        let _ = parse_dimacs_file(tmpfile).unwrap();
    }

    #[test]
    fn adds_unit_clauses() {
        let tmpfile = create_tempfile!("
            p cnf 3 4
            1 0
            2 0
            3 0
            -1 -3 0
        ");
        let cnf = parse_dimacs_file(tmpfile).unwrap();
        assert_eq!(cnf.units.len(), 3);
    }

    // TODO: Make this doc test (with unit propagate); create_tempfile may need to be an importable
    // macro up there
    #[test]
    fn unit_propagate_works() {
        let tmpfile = create_tempfile!("
            p cnf 2 2
            1 0
            1 2 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(0);
        assert!(cnf.units.is_empty());
    }

    #[test]
    fn unit_propagate_works_2() {
        let tmpfile = create_tempfile!("
            p cnf 4 4
            1 0
            1 2 0
            2 3 0
            4 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(0);
        // Only one unit clause left
        assert_eq!(cnf.units.len(), 1);
        cnf.unit_propagate(3);
        // No more unit clauses
        assert!(cnf.units.is_empty());
    }

    #[test]
    #[should_panic(expected = "unit clause not found")]
    fn unit_clause_not_found() {
        let tmpfile = create_tempfile!("
            p cnf 2 2
            1 0
            1 2 0
        ");
        let mut cnf = parse_dimacs_file(tmpfile).unwrap();
        cnf.unit_propagate(2);
    }

    #[test]
    fn zeroth_works() {
        let mut hs = HashSet::new();
        hs.insert(5);
        assert_eq!(zeroth!(hs), 5);
    }

    #[test]
    fn zeroth_works_2() {
        let mut hs = HashSet::new();
        hs.insert(5);
        hs.insert(535);
        let zth = zeroth!(hs);
        assert!(zth == 5 || zth == 535);
    }
}
<|endoftext|>


<commit_before>extern crate typenum;
use matrix::{ColumnPanelMatrix, RowPanelMatrix, Matrix, Subcomputation};
use composables::{PartM, PartN, PartK, PackA, PackB,
                  ForceB, SpawnThreads, ParallelN, TheRest};
use kern::{KernelNM};
use typenum::{UInt, B0};

// BLIS's constants
// type U4080 = UInt<UInt<typenum::U1020, B0>, B0>;
// type Nc = U4080;
// type Kc = typenum::U256;
// type Mc = typenum::U72;
// type Mr = typenum::U6;
// type Nr = typenum::U8;

type U3000 = UInt<UInt<typenum::U750, B0>, B0>;
type Nc = U3000;
type Kc = typenum::U192;
type Mc = typenum::U120;
type Mr = typenum::U4;
type Nr = typenum::U12;

type Goto<T, MTA, MTB, MTC> =
      PartN<T, MTA, MTB, MTC, Nc,
      PartK<T, MTA, MTB, MTC, Kc,
      PackB<T, MTA, MTB, MTC, ColumnPanelMatrix<T, Nr>,
      PartM<T, MTA, ColumnPanelMatrix<T,Nr>, MTC, Mc,
      PackA<T, MTA, ColumnPanelMatrix<T,Nr>, MTC, RowPanelMatrix<T,Mr>,
      ParallelN<T, RowPanelMatrix<T,Mr>, ColumnPanelMatrix<T,Nr>, MTC, Nr, TheRest,
      KernelNM<T, RowPanelMatrix<T,Mr>, ColumnPanelMatrix<T,Nr>, MTC, Nr, Mr>>>>>>>;

pub type GotoDgemm = Goto<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
pub type GotoDgemm3Sub = Subcomputation<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
pub type GotoDgemm3 =
    SpawnThreads<f64, Matrix<f64>, GotoDgemm3Sub, Matrix<f64>,
    ForceB<f64, Matrix<f64>,
           Matrix<f64>, Matrix<f64>, Matrix<f64>, GotoDgemm3Sub,
           Matrix<f64>,
    GotoDgemm, GotoDgemm>>;

    // type RootS3 = typenum::U768;
type McL2 = typenum::U120;
pub type ColPM<T> = ColumnPanelMatrix<T, Nr>;
pub type RowPM<T> = RowPanelMatrix<T, Mr>;

type L3CNc = typenum::U624;
type L3CKc = typenum::U156;
//Resident C algorithm, inner loops
type L3CInner<T, MTA, MTB, MTC> =
      PartK<T, MTA, MTB, MTC, L3CKc,
      PackB<T, MTA, MTB, MTC, ColPM<T>,
      PartM<T, MTA, ColPM<T>, MTC, L3CKc,
      PackA<T, MTA, ColPM<T>, MTC, RowPM<T>,
      ParallelN<T, RowPM<T>, ColPM<T>, MTC, Nr, TheRest,
      KernelNM<T, RowPM<T>, ColPM<T>, MTC, Nr, Mr>>>>>>;

type L3CInnerSub<T> = Subcomputation<T, Matrix<T>, Matrix<T>, ColPM<T>>;
pub type Dgemm3Sub = L3CInnerSub<f64>;
pub type Dgemm3TmpWidth = L3CNc;
pub type Dgemm3TmpHeight = L3CNc;
type L3BOuter<T, MTA, MTAi, MTBi, MTC> =
      SpawnThreads<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC,
      PartN<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC, L3CNc,
      PartK<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC, L3CNc, // Also the Mc of that algorithm, and outer k -> inner m
      ForceB<T, MTA, MTAi, MTBi, ColPM<T>, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC,
                L3CInner<T, MTAi, MTBi, ColPM<T>>,
      PartM<T, MTA, ColPM<T>, MTC, McL2,
      PartK<T, MTA, ColPM<T>, MTC, Kc,
      PackA<T, MTA, ColPM<T>, MTC, RowPM<T>,
      ParallelN<T, RowPM<T>, ColPM<T>, MTC, Nr, TheRest,
      KernelNM<T, RowPM<T>, ColPM<T>, MTC, Nr, Mr>>>>>>>>>;

pub type Dgemm3 = L3BOuter<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
<commit_msg>Switch the constants over to match BLIS<commit_after>extern crate typenum;
use matrix::{ColumnPanelMatrix, RowPanelMatrix, Matrix, Subcomputation};
use composables::{PartM, PartN, PartK, PackA, PackB,
                  ForceB, SpawnThreads, ParallelN, TheRest};
use kern::{KernelNM};
use typenum::{UInt, B0};

// BLIS's constants
type U4080 = UInt<UInt<typenum::U1020, B0>, B0>;
type Nc = U4080;
type Kc = typenum::U256;
type Mc = typenum::U72;
type Mr = typenum::U6;
type Nr = typenum::U8;

// Old constants
// type U3000 = UInt<UInt<typenum::U750, B0>, B0>;
// type Nc = U3000;
// type Kc = typenum::U192;
// type Mc = typenum::U120;
// type Mr = typenum::U4;
// type Nr = typenum::U12;

type Goto<T, MTA, MTB, MTC> =
      PartN<T, MTA, MTB, MTC, Nc,
      PartK<T, MTA, MTB, MTC, Kc,
      PackB<T, MTA, MTB, MTC, ColumnPanelMatrix<T, Nr>,
      PartM<T, MTA, ColumnPanelMatrix<T,Nr>, MTC, Mc,
      PackA<T, MTA, ColumnPanelMatrix<T,Nr>, MTC, RowPanelMatrix<T,Mr>,
      ParallelN<T, RowPanelMatrix<T,Mr>, ColumnPanelMatrix<T,Nr>, MTC, Nr, TheRest,
      KernelNM<T, RowPanelMatrix<T,Mr>, ColumnPanelMatrix<T,Nr>, MTC, Nr, Mr>>>>>>>;

pub type GotoDgemm = Goto<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
pub type GotoDgemm3Sub = Subcomputation<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
pub type GotoDgemm3 =
    SpawnThreads<f64, Matrix<f64>, GotoDgemm3Sub, Matrix<f64>,
    ForceB<f64, Matrix<f64>,
           Matrix<f64>, Matrix<f64>, Matrix<f64>, GotoDgemm3Sub,
           Matrix<f64>,
    GotoDgemm, GotoDgemm>>;

    // type RootS3 = typenum::U768;
type McL2 = typenum::U72; //typenum::U120;
pub type ColPM<T> = ColumnPanelMatrix<T, Nr>;
pub type RowPM<T> = RowPanelMatrix<T, Mr>;

type L3CNc = typenum::U624;
type L3CKc = typenum::U156;
//Resident C algorithm, inner loops
type L3CInner<T, MTA, MTB, MTC> =
      PartK<T, MTA, MTB, MTC, L3CKc,
      PackB<T, MTA, MTB, MTC, ColPM<T>,
      PartM<T, MTA, ColPM<T>, MTC, L3CKc,
      PackA<T, MTA, ColPM<T>, MTC, RowPM<T>,
      ParallelN<T, RowPM<T>, ColPM<T>, MTC, Nr, TheRest,
      KernelNM<T, RowPM<T>, ColPM<T>, MTC, Nr, Mr>>>>>>;

type L3CInnerSub<T> = Subcomputation<T, Matrix<T>, Matrix<T>, ColPM<T>>;
pub type Dgemm3Sub = L3CInnerSub<f64>;
pub type Dgemm3TmpWidth = L3CNc;
pub type Dgemm3TmpHeight = L3CNc;
type L3BOuter<T, MTA, MTAi, MTBi, MTC> =
      SpawnThreads<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC,
      PartN<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC, L3CNc,
      PartK<T, MTA, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC, L3CNc, // Also the Mc of that algorithm, and outer k -> inner m
      ForceB<T, MTA, MTAi, MTBi, ColPM<T>, Subcomputation<T, MTAi, MTBi, ColPM<T>>, MTC,
                L3CInner<T, MTAi, MTBi, ColPM<T>>,
      PartM<T, MTA, ColPM<T>, MTC, McL2,
      PartK<T, MTA, ColPM<T>, MTC, Kc,
      PackA<T, MTA, ColPM<T>, MTC, RowPM<T>,
      ParallelN<T, RowPM<T>, ColPM<T>, MTC, Nr, TheRest,
      KernelNM<T, RowPM<T>, ColPM<T>, MTC, Nr, Mr>>>>>>>>>;

pub type Dgemm3 = L3BOuter<f64, Matrix<f64>, Matrix<f64>, Matrix<f64>, Matrix<f64>>;
<|endoftext|>


<commit_before>use chrono::{DateTime, UTC};
use serde_json::Value;
use ::api::MultiOption;
use super::{Path};
use ::{Result, Error};

/// Item kind
#[derive(Debug, Clone, PartialEq)]
pub enum Kind {
	/// Folder
	Folder,
	/// File
	File,
}

/// Item
#[derive(Debug, Clone, PartialEq)]
pub struct Item {
	pub kind: Kind,
	pub id: String,
	pub url: String,
	pub name: String,
	pub filename: String,
	pub description: String,
	pub size: u64,
	pub creation_date: DateTime<UTC>,
	pub meta: Option<Value>,
}

impl Item {
	pub fn path(self) -> Path {
		Path::Id(self.id.clone())
	}

	pub fn from_value(value: Value, with_meta: bool) -> Result<MultiOption<Item>> {
		// Check if we have one item or many
		match value.find("odata.count") {
			Some(_) => {
				let mut items = Vec::new();
				for val in value.find("value").unwrap().as_array().unwrap() {
					match Item::item_from_value(val, with_meta) {
						Ok(item) => items.push(item),
						Err(err) => return err.result()
					};
				}

				Ok(MultiOption::Many(items))
			},
			None => {
				match Item::item_from_value(&value, with_meta) {
					Ok(item) => Ok(MultiOption::One(item)),
					Err(err) => return err.result()
				}
			}
		}
	}

	fn item_from_value(value: &Value, with_meta: bool) -> Result<Item> {
		let kind = match value.find("odata.type") {
			Some(otype) => match otype.as_string().unwrap() {
				"ShareFile.Api.Models.Folder" => Kind::Folder,
				"ShareFile.Api.Models.File" => Kind::File,
				k => return Error::new(format!("Unknown item kind {}.", k)).result()
			},
			None => {
				return Error::new("Item.odata.type property is missing.").result();
			}
		};

		let id = match value.find("Id") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Id property is missing.").result()
		};

		let url = match value.find("url") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.url property is missing.").result()
		};

		let name = match value.find("Name") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Name property is missing.").result()
		};

		let filename = match value.find("FileName") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.FileName property is missing.").result()
		};

		let description = match value.find("Description") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Description property is missing.").result()
		};

		let size = match value.find("FileSizeBytes") {
			Some(v) => v.as_u64().unwrap(),
			None => return Error::new("Item.FileSizeBytes property is missing.").result()
		};

		let creation_date = match value.find("CreationDate") {
			Some(v) => match v.as_string().unwrap().parse::<DateTime<UTC>>() {
				Ok(dt) => dt,
				Err(err) => return Error::new("Item.CreationDate property is invalid").because(err).result()
			},
			None => return Error::new("Item.CreationDate property is missing.").result()
		};

		let meta = if with_meta {
			Some(value.clone())
		}
		else {
			None
		};

		Ok(Item {
			kind: kind,
			id: id.to_owned(),
			url: url.to_owned(),
			name: name.to_owned(),
			filename: filename.to_owned(),
			description: description.to_owned(),
			size: size,
			creation_date: creation_date,
			meta: meta,
		})
	}
}
<commit_msg>Fix to &self<commit_after>use chrono::{DateTime, UTC};
use serde_json::Value;
use ::api::MultiOption;
use super::{Path};
use ::{Result, Error};

/// Item kind
#[derive(Debug, Clone, PartialEq)]
pub enum Kind {
	/// Folder
	Folder,
	/// File
	File,
}

/// Item
#[derive(Debug, Clone, PartialEq)]
pub struct Item {
	pub kind: Kind,
	pub id: String,
	pub url: String,
	pub name: String,
	pub filename: String,
	pub description: String,
	pub size: u64,
	pub creation_date: DateTime<UTC>,
	pub meta: Option<Value>,
}

impl Item {
	pub fn path(&self) -> Path {
		Path::Id(self.id.clone())
	}

	pub fn from_value(value: Value, with_meta: bool) -> Result<MultiOption<Item>> {
		// Check if we have one item or many
		match value.find("odata.count") {
			Some(_) => {
				let mut items = Vec::new();
				for val in value.find("value").unwrap().as_array().unwrap() {
					match Item::item_from_value(val, with_meta) {
						Ok(item) => items.push(item),
						Err(err) => return err.result()
					};
				}

				Ok(MultiOption::Many(items))
			},
			None => {
				match Item::item_from_value(&value, with_meta) {
					Ok(item) => Ok(MultiOption::One(item)),
					Err(err) => return err.result()
				}
			}
		}
	}

	fn item_from_value(value: &Value, with_meta: bool) -> Result<Item> {
		let kind = match value.find("odata.type") {
			Some(otype) => match otype.as_string().unwrap() {
				"ShareFile.Api.Models.Folder" => Kind::Folder,
				"ShareFile.Api.Models.File" => Kind::File,
				k => return Error::new(format!("Unknown item kind {}.", k)).result()
			},
			None => {
				return Error::new("Item.odata.type property is missing.").result();
			}
		};

		let id = match value.find("Id") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Id property is missing.").result()
		};

		let url = match value.find("url") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.url property is missing.").result()
		};

		let name = match value.find("Name") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Name property is missing.").result()
		};

		let filename = match value.find("FileName") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.FileName property is missing.").result()
		};

		let description = match value.find("Description") {
			Some(v) => v.as_string().unwrap(),
			None => return Error::new("Item.Description property is missing.").result()
		};

		let size = match value.find("FileSizeBytes") {
			Some(v) => v.as_u64().unwrap(),
			None => return Error::new("Item.FileSizeBytes property is missing.").result()
		};

		let creation_date = match value.find("CreationDate") {
			Some(v) => match v.as_string().unwrap().parse::<DateTime<UTC>>() {
				Ok(dt) => dt,
				Err(err) => return Error::new("Item.CreationDate property is invalid").because(err).result()
			},
			None => return Error::new("Item.CreationDate property is missing.").result()
		};

		let meta = if with_meta {
			Some(value.clone())
		}
		else {
			None
		};

		Ok(Item {
			kind: kind,
			id: id.to_owned(),
			url: url.to_owned(),
			name: name.to_owned(),
			filename: filename.to_owned(),
			description: description.to_owned(),
			size: size,
			creation_date: creation_date,
			meta: meta,
		})
	}
}
<|endoftext|>


<commit_before>use std::borrow;
use std::collections;
use std::env;
use std::fs;
use std::io::Write;
use std::path;

use clap;
use cobalt::cobalt_model;

use args;
use error::*;

pub fn init_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("init")
        .about("create a new cobalt project")
        .arg(
            clap::Arg::with_name("DIRECTORY")
                .help("Target directory")
                .default_value("./")
                .index(1),
        )
}

pub fn init_command(matches: &clap::ArgMatches) -> Result<()> {
    let directory = matches.value_of("DIRECTORY").unwrap();

    create_new_project(&directory.to_string())
        .chain_err(|| "Could not create a new cobalt project")?;
    info!("Created new project at {}", directory);

    Ok(())
}

pub fn new_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("new")
        .about("Create a document")
        .args(&args::get_config_args())
        .arg(
            clap::Arg::with_name("TITLE")
                .required(true)
                .help("Title of the post")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("file")
                .short("f")
                .long("file")
                .value_name("DIR_OR_FILE")
                .help("New document's parent directory or file (default: `<CWD>/title.ext`)")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("with-ext")
                .long("with-ext")
                .value_name("EXT")
                .help("The default file's extension (e.g. `liquid`)")
                .takes_value(true),
        )
}

pub fn new_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    let title = matches.value_of("TITLE").unwrap();

    let mut file = env::current_dir().expect("How does this fail?");
    if let Some(rel_file) = matches.value_of("file") {
        file.push(path::Path::new(rel_file))
    }

    let ext = matches.value_of("with-ext");

    create_new_document(&config, title, file, ext)
        .chain_err(|| format!("Could not create `{}`", title))?;

    Ok(())
}

pub fn publish_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("publish")
        .about("Publish a document")
        .arg(
            clap::Arg::with_name("FILENAME")
                .required(true)
                .help("Document path to publish")
                .takes_value(true),
        )
}

pub fn publish_command(matches: &clap::ArgMatches) -> Result<()> {
    let file = matches
        .value_of("FILENAME")
        .expect("required parameters are present");
    let file = path::Path::new(file);

    publish_document(file).chain_err(|| format!("Could not publish `{:?}`", file))?;

    Ok(())
}

const COBALT_YML: &str = "
site:
  title: cobalt blog
  description: Blog Posts Go Here
  base_url: http://example.com
posts:
  rss: rss.xml
";

const DEFAULT_LAYOUT: &str = "<!DOCTYPE html>

        <meta charset=\"utf-8\">
        <title>{{ page.title }}</title>

{{ page.title }}

      {{ page.content }}

";

const POST_MD: &str = "layout: default.liquid

title: First Post
is_draft: true
---

# This is our first Post!

Welcome to the first post ever on cobalt.rs!
";

const INDEX_MD: &str = "layout: default.liquid
---
## Blog!

{% for post in collections.posts.pages %}
#### {{post.title}}

[{{ post.title }}]({{ post.permalink }})
{% endfor %}
";

lazy_static! {
    static ref DEFAULT: collections::HashMap<&'static str, &'static str> = [("pages", INDEX_MD), ("posts", POST_MD)].iter().map(|e| e.clone()).collect();
}

pub fn create_new_project<P: AsRef<path::Path>>(dest: P) -> Result<()> {
    create_new_project_for_path(dest.as_ref())
}

pub fn create_new_project_for_path(dest: &path::Path) -> Result<()> {
    fs::create_dir_all(dest)?;

    create_file(&dest.join("_cobalt.yml"), COBALT_YML)?;
    create_file(&dest.join("index.md"), INDEX_MD)?;

    fs::create_dir_all(&dest.join("_layouts"))?;
    create_file(&dest.join("_layouts/default.liquid"), DEFAULT_LAYOUT)?;

    fs::create_dir_all(&dest.join("posts"))?;
    create_file(&dest.join("posts/post-1.md"), POST_MD)?;

    fs::create_dir_all(&dest.join("_defaults"))?;
    create_file(&dest.join("_defaults/pages.md"), INDEX_MD)?;
    create_file(&dest.join("_defaults/posts.md"), POST_MD)?;

    Ok(())
}

pub fn create_new_document(
    config: &cobalt_model::Config,
    title: &str,
    file: path::PathBuf,
    extension: Option<&str>,
) -> Result<()> {
    let (file, extension) = if file.extension().is_none() || file.is_dir() {
        let extension = extension.unwrap_or("md");
        let file_name = format!("{}.{}", cobalt_model::slug::slugify(title), extension);
        let mut file = file;
        file.push(path::Path::new(&file_name));
        (file, borrow::Cow::Borrowed(extension))
    } else {
        // The user-provided extension will be used for selecting a template
        let extension = extension.map(borrow::Cow::Borrowed).unwrap_or_else(|| {
            borrow::Cow::Owned(
                file.extension()
                    .unwrap_or_default()
                    .to_str()
                    .unwrap_or_default()
                    .to_string(),
            )
        });
        (file, extension)
    };

    let rel_file = file.strip_prefix(&config.source).map_err(|_| {
        format!(
            "New file {:?} not project directory ({:?})",
            file, config.source
        )
    })?;

    let pages = config.pages.clone().build()?;
    let posts = config.posts.clone().build()?;
    let file_type = if posts.pages.includes_file(&file)
        || posts
            .drafts
            .map(|d| d.includes_file(&file))
            .unwrap_or_default()
    {
        posts.slug.as_str()
    } else if pages.pages.includes_file(&file)
        || pages
            .drafts
            .map(|d| d.includes_file(&file))
            .unwrap_or_default()
    {
        pages.slug.as_str()
    } else {
        bail!(
            "Target file wouldn't be a member of any collection: {:?}",
            file
        );
    };

    let source_path = config
        .source
        .join(format!("_defaults/{}.{}", file_type, extension));
    let source = if source_path.is_file() {
        cobalt_model::files::read_file(&source_path)
            .chain_err(|| format!("Failed to read default: {:?}", source_path))?
    } else {
        debug!(
            "No custom default provided ({:?}), falling back to built-in",
            source_path
        );
        if extension != "md" {
            bail!(
                "No builtin default for `{}` files, only `md`: {:?}",
                extension,
                file
            );
        }
        // For custom collections, use a post default.
        DEFAULT.get(file_type).unwrap_or(&POST_MD).to_string()
    };

    let doc = cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::parse(&source)?;
    let (front, content) = doc.parts();
    let front = front.set_title(title.to_owned());
    let doc =
        cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::new(front, content);
    let doc = doc.to_string();

    create_file(&file, &doc)?;
    info!("Created new {} {:?}", file_type, rel_file);

    Ok(())
}

fn create_file<P: AsRef<path::Path>>(path: P, content: &str) -> Result<()> {
    create_file_for_path(path.as_ref(), content)
}

fn create_file_for_path(path: &path::Path, content: &str) -> Result<()> {
    trace!("Creating file {:?}", path);

    let mut file = fs::OpenOptions::new()
        .write(true)
        .create_new(true)
        .open(path)
        .chain_err(|| format!("Failed to create file {:?}", path))?;

    file.write_all(content.as_bytes())?;

    Ok(())
}

pub fn publish_document(file: &path::Path) -> Result<()> {
    let doc = cobalt_model::files::read_file(file)?;
    let doc = cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::parse(&doc)?;
    let (front, content) = doc.parts();

    let date = cobalt_model::DateTime::now();
    let front = front.set_draft(false).set_published_date(date);

    let doc =
        cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::new(front, content);
    let doc = doc.to_string();

    cobalt_model::files::write_document_file(doc, file)?;

    Ok(())
}
<commit_msg>style: Address clippy<commit_after>use std::borrow;
use std::collections;
use std::env;
use std::fs;
use std::io::Write;
use std::path;

use clap;
use cobalt::cobalt_model;

use args;
use error::*;

pub fn init_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("init")
        .about("create a new cobalt project")
        .arg(
            clap::Arg::with_name("DIRECTORY")
                .help("Target directory")
                .default_value("./")
                .index(1),
        )
}

pub fn init_command(matches: &clap::ArgMatches) -> Result<()> {
    let directory = matches.value_of("DIRECTORY").unwrap();

    create_new_project(&directory.to_string())
        .chain_err(|| "Could not create a new cobalt project")?;
    info!("Created new project at {}", directory);

    Ok(())
}

pub fn new_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("new")
        .about("Create a document")
        .args(&args::get_config_args())
        .arg(
            clap::Arg::with_name("TITLE")
                .required(true)
                .help("Title of the post")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("file")
                .short("f")
                .long("file")
                .value_name("DIR_OR_FILE")
                .help("New document's parent directory or file (default: `<CWD>/title.ext`)")
                .takes_value(true),
        )
        .arg(
            clap::Arg::with_name("with-ext")
                .long("with-ext")
                .value_name("EXT")
                .help("The default file's extension (e.g. `liquid`)")
                .takes_value(true),
        )
}

pub fn new_command(matches: &clap::ArgMatches) -> Result<()> {
    let config = args::get_config(matches)?;
    let config = config.build()?;

    let title = matches.value_of("TITLE").unwrap();

    let mut file = env::current_dir().expect("How does this fail?");
    if let Some(rel_file) = matches.value_of("file") {
        file.push(path::Path::new(rel_file))
    }

    let ext = matches.value_of("with-ext");

    create_new_document(&config, title, file, ext)
        .chain_err(|| format!("Could not create `{}`", title))?;

    Ok(())
}

pub fn publish_command_args() -> clap::App<'static, 'static> {
    clap::SubCommand::with_name("publish")
        .about("Publish a document")
        .arg(
            clap::Arg::with_name("FILENAME")
                .required(true)
                .help("Document path to publish")
                .takes_value(true),
        )
}

pub fn publish_command(matches: &clap::ArgMatches) -> Result<()> {
    let file = matches
        .value_of("FILENAME")
        .expect("required parameters are present");
    let file = path::Path::new(file);

    publish_document(file).chain_err(|| format!("Could not publish `{:?}`", file))?;

    Ok(())
}

const COBALT_YML: &str = "
site:
  title: cobalt blog
  description: Blog Posts Go Here
  base_url: http://example.com
posts:
  rss: rss.xml
";

const DEFAULT_LAYOUT: &str = "<!DOCTYPE html>

        <meta charset=\"utf-8\">
        <title>{{ page.title }}</title>

{{ page.title }}

      {{ page.content }}

";

const POST_MD: &str = "layout: default.liquid

title: First Post
is_draft: true
---

# This is our first Post!

Welcome to the first post ever on cobalt.rs!
";

const INDEX_MD: &str = "layout: default.liquid
---
## Blog!

{% for post in collections.posts.pages %}
#### {{post.title}}

[{{ post.title }}]({{ post.permalink }})
{% endfor %}
";

lazy_static! {
    static ref DEFAULT: collections::HashMap<&'static str, &'static str> = [("pages", INDEX_MD), ("posts", POST_MD)].iter().cloned().collect();
}

pub fn create_new_project<P: AsRef<path::Path>>(dest: P) -> Result<()> {
    create_new_project_for_path(dest.as_ref())
}

pub fn create_new_project_for_path(dest: &path::Path) -> Result<()> {
    fs::create_dir_all(dest)?;

    create_file(&dest.join("_cobalt.yml"), COBALT_YML)?;
    create_file(&dest.join("index.md"), INDEX_MD)?;

    fs::create_dir_all(&dest.join("_layouts"))?;
    create_file(&dest.join("_layouts/default.liquid"), DEFAULT_LAYOUT)?;

    fs::create_dir_all(&dest.join("posts"))?;
    create_file(&dest.join("posts/post-1.md"), POST_MD)?;

    fs::create_dir_all(&dest.join("_defaults"))?;
    create_file(&dest.join("_defaults/pages.md"), INDEX_MD)?;
    create_file(&dest.join("_defaults/posts.md"), POST_MD)?;

    Ok(())
}

pub fn create_new_document(
    config: &cobalt_model::Config,
    title: &str,
    file: path::PathBuf,
    extension: Option<&str>,
) -> Result<()> {
    let (file, extension) = if file.extension().is_none() || file.is_dir() {
        let extension = extension.unwrap_or("md");
        let file_name = format!("{}.{}", cobalt_model::slug::slugify(title), extension);
        let mut file = file;
        file.push(path::Path::new(&file_name));
        (file, borrow::Cow::Borrowed(extension))
    } else {
        // The user-provided extension will be used for selecting a template
        let extension = extension.map(borrow::Cow::Borrowed).unwrap_or_else(|| {
            borrow::Cow::Owned(
                file.extension()
                    .unwrap_or_default()
                    .to_str()
                    .unwrap_or_default()
                    .to_string(),
            )
        });
        (file, extension)
    };

    let rel_file = file.strip_prefix(&config.source).map_err(|_| {
        format!(
            "New file {:?} not project directory ({:?})",
            file, config.source
        )
    })?;

    let pages = config.pages.clone().build()?;
    let posts = config.posts.clone().build()?;
    let file_type = if posts.pages.includes_file(&file)
        || posts
            .drafts
            .map(|d| d.includes_file(&file))
            .unwrap_or_default()
    {
        posts.slug.as_str()
    } else if pages.pages.includes_file(&file)
        || pages
            .drafts
            .map(|d| d.includes_file(&file))
            .unwrap_or_default()
    {
        pages.slug.as_str()
    } else {
        bail!(
            "Target file wouldn't be a member of any collection: {:?}",
            file
        );
    };

    let source_path = config
        .source
        .join(format!("_defaults/{}.{}", file_type, extension));
    let source = if source_path.is_file() {
        cobalt_model::files::read_file(&source_path)
            .chain_err(|| format!("Failed to read default: {:?}", source_path))?
    } else {
        debug!(
            "No custom default provided ({:?}), falling back to built-in",
            source_path
        );
        if extension != "md" {
            bail!(
                "No builtin default for `{}` files, only `md`: {:?}",
                extension,
                file
            );
        }
        // For custom collections, use a post default.
        DEFAULT.get(file_type).unwrap_or(&POST_MD).to_string()
    };

    let doc = cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::parse(&source)?;
    let (front, content) = doc.parts();
    let front = front.set_title(title.to_owned());
    let doc =
        cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::new(front, content);
    let doc = doc.to_string();

    create_file(&file, &doc)?;
    info!("Created new {} {:?}", file_type, rel_file);

    Ok(())
}

fn create_file<P: AsRef<path::Path>>(path: P, content: &str) -> Result<()> {
    create_file_for_path(path.as_ref(), content)
}

fn create_file_for_path(path: &path::Path, content: &str) -> Result<()> {
    trace!("Creating file {:?}", path);

    let mut file = fs::OpenOptions::new()
        .write(true)
        .create_new(true)
        .open(path)
        .chain_err(|| format!("Failed to create file {:?}", path))?;

    file.write_all(content.as_bytes())?;

    Ok(())
}

pub fn publish_document(file: &path::Path) -> Result<()> {
    let doc = cobalt_model::files::read_file(file)?;
    let doc = cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::parse(&doc)?;
    let (front, content) = doc.parts();

    let date = cobalt_model::DateTime::now();
    let front = front.set_draft(false).set_published_date(date);

    let doc =
        cobalt_model::DocumentBuilder::<cobalt_model::FrontmatterBuilder>::new(front, content);
    let doc = doc.to_string();

    cobalt_model::files::write_document_file(doc, file)?;

    Ok(())
}
<|endoftext|>


<commit_before>#![crate_name = "kernel"]
#![crate_type = "staticlib"]
#![no_std]
#![feature(asm, lang_items)]
#![feature(core)]

extern crate core;
extern crate rlibc;

#[path = "arch/x86/"]
pub mod platform {
	pub mod vga;
	pub mod cpu;
	pub mod mmu;
	mod io;
	pub mod keyboard;
}

pub mod kernel {
	pub mod main;
	pub mod interrupts;
	mod stdio;
	mod keyboard;
}

// Remove this when https://github.com/rust-lang/rust/issues/21827 is solved
mod std {
    pub mod option {
        pub use core::option::*;
    }
    pub mod iter {
        pub use core::iter::*;
    }
}

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
<commit_msg>Add macro_use to allow usages of panic! and sorts<commit_after>#![crate_name = "kernel"]
#![crate_type = "staticlib"]
#![no_std]
#![feature(asm, lang_items)]
#![feature(core)]

#[macro_use] extern crate core;
extern crate rlibc;

#[path = "arch/x86/"]
pub mod platform {
	pub mod vga;
	pub mod cpu;
	pub mod mmu;
	mod io;
	pub mod keyboard;
}

pub mod kernel {
	pub mod main;
	pub mod interrupts;
	mod stdio;
	mod keyboard;
}

// Remove this when https://github.com/rust-lang/rust/issues/21827 is solved
mod std {
    pub mod option {
        pub use core::option::*;
    }
    pub mod iter {
        pub use core::iter::*;
    }
}

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
<|endoftext|>