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

struct ret;
struct obj;

impl obj {
    fn func() -> ret {
        ret
    }
}

fn func() -> ret {
    ret
}

fn main() {
    obj::func.x();
    //~^ ERROR no method named `x` found for type `fn() -> ret {obj::func}` in the current scope
    //~^^ NOTE obj::func is a function, perhaps you wish to call it
    func.x();
    //~^ ERROR no method named `x` found for type `fn() -> ret {func}` in the current scope
    //~^^ NOTE func is a function, perhaps you wish to call it
}
<commit_msg>Add Help and Suggestion to issue-29124 tests<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct ret;
struct obj;

impl obj {
    fn func() -> ret {
        ret
    }
}

fn func() -> ret {
    ret
}

fn main() {
    obj::func.x();
    //~^ ERROR no method named `x` found for type `fn() -> ret {obj::func}` in the current scope
    //~^^ NOTE obj::func is a function, perhaps you wish to call it
    //~^^^ HELP try calling the base function:
    //~| SUGGESTION obj::func().x();
    func.x();
    //~^ ERROR no method named `x` found for type `fn() -> ret {func}` in the current scope
    //~^^ NOTE func is a function, perhaps you wish to call it
    //~^^^ HELP try calling the base function:
    //~| SUGGESTION func().x();
}
<|endoftext|>


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

// This checks that a path that cannot be resolved because of an indeterminate import
// does not trigger an ICE.

mod foo {
    pub use self::*; //~ ERROR unresolved
}

fn main() {
    foo::f(); //~ ERROR unresolved
}
<|endoftext|>


<commit_before><commit_msg>use neg_assign<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Use VcardBuilder instead of Vcard itself<commit_after><|endoftext|>


<commit_before>extern crate libc;

use std::io;
use std::io::fs;
use std::io::File;
use std::path::Path;
use std::collections::HashMap;

use document::Document;

pub struct Runner;

impl Runner {
    pub fn run(path_string: &str) {
        let base_path      = Path::new(path_string);
        let documents_path = base_path.join("_posts");
        let layout_path    = base_path.join("_layouts");
        let index_path     = base_path.join("index.tpl");
        let build_path     = base_path.join("build");

        println!("Generating site in {}\n", path_string);

        let index     = Runner::parse_document(&index_path);
        let posts     = Runner::parse_documents(&documents_path);
        let post_path = Runner::create_dirs(&build_path);

        Runner::create_files(&build_path, &post_path, &layout_path, index, posts);
    }

    fn parse_documents(path: &Path) -> Vec<Document> {
        match fs::readdir(path) {
            Ok(paths) => paths.iter().filter_map( |path|
                    if path.extension_str().unwrap() == "tpl" {
                        Some(Runner::parse_document(path))
                    }else{
                        None
                    }
                ).collect(),
            // TODO panic!
            Err(e) => fail!("Path {} doesn't exist\n", path.display())
        }
    }

    fn parse_document(path: &Path) -> Document {
        let attributes = Runner::extract_attributes(path);
        let content    = Runner::extract_content(path);

        Document::new(
            attributes,
            content,
            path.filestem_str().unwrap().to_string() + ".html",
        )
    }

    fn parse_file(path: &Path) -> String {
        match File::open(path) {
            // TODO handle IOResult
            Ok(mut x) => x.read_to_string().unwrap(),
            // TODO panic!
            Err(e) => fail!("File {} doesn't exist\n", path.display())
        }
    }

    fn create_dirs(build_path: &Path) -> Path {
        let postpath = build_path.join("posts");

        fs::mkdir(build_path, io::USER_RWX);
        fs::mkdir(&postpath, io::USER_RWX);

        // TODO: copy non cobalt relevant folders into /build folder (assets, stylesheets, etc...)

        println!("Directory {} created\n", build_path.display());

        return postpath;
    }

    fn create_files(index_path: &Path, document_path: &Path, layout_path: &Path, index: Document, documents: Vec<Document>) {
        index.create_file(index_path, layout_path);

        for document in documents.iter() {
            document.create_file(document_path, layout_path);
        }
    }

    fn extract_attributes(path: &Path) -> HashMap<String, String> {
        let mut attributes = HashMap::new();
        attributes.insert("name".to_string(), path.filestem_str().unwrap().to_string());

        let content = Runner::parse_file(path);

        if content.as_slice().contains("---") {
            let mut content_splits = content.as_slice().split_str("---");

            let attribute_string = content_splits.nth(0u).unwrap();

            for attribute_line in attribute_string.split_str("\n") {
                if !attribute_line.contains_char(':') {
                    continue;
                }

                let mut attribute_split = attribute_line.split(':');

                // TODO: Refactor, find a better way for doing this
                // .nth() method is consuming the iterator and therefore the 0th index on the second method
                // is in real index 1
                let key   = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();
                let value = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();

                attributes.insert(key, value);
            }
        }

        return attributes;
    }

    fn extract_content(path: &Path) -> String {
        let content = Runner::parse_file(path);

        if content.as_slice().contains("---") {
            let mut content_splits = content.as_slice().split_str("---");

            return content_splits.nth(1u).unwrap().to_string();
        }

        return content;
    }
}
<commit_msg>use _ if variable isn't used in matched block<commit_after>extern crate libc;

use std::io;
use std::io::fs;
use std::io::File;
use std::path::Path;
use std::collections::HashMap;

use document::Document;

pub struct Runner;

impl Runner {
    pub fn run(path_string: &str) {
        let base_path      = Path::new(path_string);
        let documents_path = base_path.join("_posts");
        let layout_path    = base_path.join("_layouts");
        let index_path     = base_path.join("index.tpl");
        let build_path     = base_path.join("build");

        println!("Generating site in {}\n", path_string);

        let index     = Runner::parse_document(&index_path);
        let posts     = Runner::parse_documents(&documents_path);
        let post_path = Runner::create_dirs(&build_path);

        Runner::create_files(&build_path, &post_path, &layout_path, index, posts);
    }

    fn parse_documents(path: &Path) -> Vec<Document> {
        match fs::readdir(path) {
            Ok(paths) => paths.iter().filter_map( |path|
                    if path.extension_str().unwrap() == "tpl" {
                        Some(Runner::parse_document(path))
                    }else{
                        None
                    }
                ).collect(),
            // TODO panic!
            Err(_) => fail!("Path {} doesn't exist\n", path.display())
        }
    }

    fn parse_document(path: &Path) -> Document {
        let attributes = Runner::extract_attributes(path);
        let content    = Runner::extract_content(path);

        Document::new(
            attributes,
            content,
            path.filestem_str().unwrap().to_string() + ".html",
        )
    }

    fn parse_file(path: &Path) -> String {
        match File::open(path) {
            // TODO handle IOResult
            Ok(mut x) => x.read_to_string().unwrap(),
            // TODO panic!
            Err(_) => fail!("File {} doesn't exist\n", path.display())
        }
    }

    fn create_dirs(build_path: &Path) -> Path {
        let postpath = build_path.join("posts");

        fs::mkdir(build_path, io::USER_RWX);
        fs::mkdir(&postpath, io::USER_RWX);

        // TODO: copy non cobalt relevant folders into /build folder (assets, stylesheets, etc...)

        println!("Directory {} created\n", build_path.display());

        return postpath;
    }

    fn create_files(index_path: &Path, document_path: &Path, layout_path: &Path, index: Document, documents: Vec<Document>) {
        index.create_file(index_path, layout_path);

        for document in documents.iter() {
            document.create_file(document_path, layout_path);
        }
    }

    fn extract_attributes(path: &Path) -> HashMap<String, String> {
        let mut attributes = HashMap::new();
        attributes.insert("name".to_string(), path.filestem_str().unwrap().to_string());

        let content = Runner::parse_file(path);

        if content.as_slice().contains("---") {
            let mut content_splits = content.as_slice().split_str("---");

            let attribute_string = content_splits.nth(0u).unwrap();

            for attribute_line in attribute_string.split_str("\n") {
                if !attribute_line.contains_char(':') {
                    continue;
                }

                let mut attribute_split = attribute_line.split(':');

                // TODO: Refactor, find a better way for doing this
                // .nth() method is consuming the iterator and therefore the 0th index on the second method
                // is in real index 1
                let key   = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();
                let value = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();

                attributes.insert(key, value);
            }
        }

        return attributes;
    }

    fn extract_content(path: &Path) -> String {
        let content = Runner::parse_file(path);

        if content.as_slice().contains("---") {
            let mut content_splits = content.as_slice().split_str("---");

            return content_splits.nth(1u).unwrap().to_string();
        }

        return content;
    }
}
<|endoftext|>


<commit_before>extern crate core;

use std::io;
use std::fs;
use std::fs::PathExt;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::collections::HashMap;
use self::core::str::StrExt;
use std::ffi::OsStr;
use liquid::Value;

use document::Document;
use util;

pub fn build(source: &Path, dest: &Path, layout_str: &str, posts_str: &str) -> io::Result<()>{
    // TODO make configurable
    let template_extensions = [OsStr::new("tpl") /*, OsStr::new("md")*/];

    let layouts_path = source.join(layout_str);
    let posts_path = source.join(posts_str);

    let mut layouts : HashMap<String, String> = HashMap::new();

    // go through the layout directory and add
    // filename -> text content to the layout map
    match fs::walk_dir(&layouts_path) {
        Ok(files) => for layout in files {
            let layout = try!(layout).path();
            if layout.is_file() {
                let mut text = String::new();
                try!(try!(File::open(&layout)).read_to_string(&mut text));
                layouts.insert(layout.as_path().file_name().unwrap().to_str().unwrap().to_string(), text);
            }
        },
        Err(_) => println!("Warning: No layout path found ({})\n", source.display())
    };

    let mut documents = vec![];
    let mut post_data = vec![];

    // walk source directory and find files that are written in
    // a template file extension
    for p in try!(fs::walk_dir(source)) {
        let p = p.unwrap().path();
        let path = p.as_path();
        // check for file extensions
        if template_extensions.contains(&path.extension().unwrap_or(OsStr::new("")))
        // check that file is not in the layouts folder
        && path.parent() != Some(layouts_path.as_path()) {
            let doc = parse_document(&path, source);
            if path.parent() == Some(posts_path.as_path()){
                post_data.push(Value::Object(doc.get_attributes()));
            }
            documents.push(doc);
        }
    }

    for doc in documents.iter() {
        try!(doc.create_file(dest, &layouts, &post_data));
    }

    // copy everything
    if source != dest {
        try!(util::copy_recursive_filter(source, dest, &|p| -> bool {
            !p.file_name().unwrap().to_str().unwrap_or("").starts_with(".")
            && !template_extensions.contains(&p.extension().unwrap_or(OsStr::new("")))
            && p != dest
            && p != layouts_path.as_path()
        }));
    }

    Ok(())
}

fn parse_document(path: &Path, source: &Path) -> Document {
    let attributes = extract_attributes(path);
    let content    = extract_content(path).unwrap();
    let new_path   = path.relative_from(source).unwrap();
    // let markdown   = path.extension().unwrap_or(OsStr::new("")) == OsStr::new("md");

    Document::new(
        new_path.to_str().unwrap().to_string(),
        attributes,
        content,
        // markdown
    )
}

fn parse_file(path: &Path) -> io::Result<String> {
    let mut file = try!(File::open(path));
    let mut text = String::new();
    try!(file.read_to_string(&mut text));
    Ok(text)
}

fn extract_attributes(path: &Path) -> HashMap<String, String> {
    let mut attributes = HashMap::new();
    attributes.insert("name".to_string(), path.file_stem().unwrap().to_str().unwrap().to_string());

    let content = parse_file(path).unwrap();

    if content.contains("---") {
        let mut content_splits = content.split("---");

        let attribute_string = content_splits.nth(0).unwrap();

        for attribute_line in attribute_string.split("\n") {
            if !attribute_line.contains_char(':') {
                continue;
            }

            let mut attribute_split = attribute_line.split(':');

            // TODO: Refactor, find a better way for doing this
            // .nth() method is consuming the iterator and therefore the 0th index on the second method
            // is in real index 1
            let key   = attribute_split.nth(0).unwrap().trim_matches(' ').to_string().clone();
            let value = attribute_split.nth(0).unwrap().trim_matches(' ').to_string().clone();

            attributes.insert(key, value);
        }
    }

    return attributes;
}

fn extract_content(path: &Path) -> io::Result<String> {
    let content = try!(parse_file(path));

    if content.contains("---") {
        let mut content_splits = content.split("---");

        return Ok(content_splits.nth(1).unwrap().to_string());
    }

    return Ok(content);
}
<commit_msg>readability<commit_after>extern crate core;

use std::io;
use std::fs;
use std::fs::PathExt;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::collections::HashMap;
use self::core::str::StrExt;
use std::ffi::OsStr;
use liquid::Value;

use document::Document;
use util;

pub fn build(source: &Path, dest: &Path, layout_str: &str, posts_str: &str) -> io::Result<()>{
    // TODO make configurable
    let template_extensions = [OsStr::new("tpl") /*, OsStr::new("md")*/];

    let layouts_path = source.join(layout_str);
    let posts_path = source.join(posts_str);

    let mut layouts : HashMap<String, String> = HashMap::new();

    // go through the layout directory and add
    // filename -> text content to the layout map
    match fs::walk_dir(&layouts_path) {
        Ok(files) => for layout in files {
            let layout = try!(layout).path();
            if layout.is_file() {
                let mut text = String::new();
                try!(try!(File::open(&layout)).read_to_string(&mut text));
                layouts.insert(layout.as_path().file_name().unwrap().to_str().unwrap().to_string(), text);
            }
        },
        Err(_) => println!("Warning: No layout path found ({})\n", source.display())
    };

    let mut documents = vec![];
    let mut post_data = vec![];

    // walk source directory and find files that are written in
    // a template file extension
    for p in try!(fs::walk_dir(source)) {
        let p = p.unwrap().path();
        let path = p.as_path();
        // check for file extensions
        if template_extensions.contains(&path.extension().unwrap_or(OsStr::new("")))
        // check that file is not in the layouts folder
        && path.parent() != Some(layouts_path.as_path()) {
            let doc = parse_document(&path, source);
            if path.parent() == Some(posts_path.as_path()){
                post_data.push(Value::Object(doc.get_attributes()));
            }
            documents.push(doc);
        }
    }

    for doc in documents.iter() {
        try!(doc.create_file(dest, &layouts, &post_data));
    }

    // copy everything
    if source != dest {
        try!(util::copy_recursive_filter(source, dest, &|p| -> bool {
            !p.file_name().unwrap().to_str().unwrap_or("").starts_with(".")
            && !template_extensions.contains(&p.extension().unwrap_or(OsStr::new("")))
            && p != dest
            && p != layouts_path.as_path()
        }));
    }

    Ok(())
}

fn parse_document(path: &Path, source: &Path) -> Document {
    let attributes = extract_attributes(path);
    let content    = extract_content(path).unwrap();
    let new_path   = path.relative_from(source).unwrap();
    // let markdown   = path.extension().unwrap_or(OsStr::new("")) == OsStr::new("md");

    Document::new(
        new_path.to_str().unwrap().to_string(),
        attributes,
        content,
        // markdown
    )
}

fn parse_file(path: &Path) -> io::Result<String> {
    let mut file = try!(File::open(path));
    let mut text = String::new();
    try!(file.read_to_string(&mut text));
    Ok(text)
}

fn extract_attributes(path: &Path) -> HashMap<String, String> {
    let mut attributes = HashMap::new();
    attributes.insert("name".to_string(), path.file_stem().unwrap().to_str().unwrap().to_string());

    let content = parse_file(path).unwrap();

    if content.contains("---") {
        let mut content_splits = content.split("---");

        let attribute_string = content_splits.nth(0).unwrap();

        for attribute_line in attribute_string.split("\n") {
            if !attribute_line.contains_char(':') {
                continue;
            }

            let attribute_split: Vec<&str> = attribute_line.split(':').collect();

            let key   = attribute_split[0].trim_matches(' ').to_string().clone();
            let value = attribute_split[1].trim_matches(' ').to_string().clone();

            attributes.insert(key, value);
        }
    }

    return attributes;
}

fn extract_content(path: &Path) -> io::Result<String> {
    let content = try!(parse_file(path));

    if content.contains("---") {
        let mut content_splits = content.split("---");

        return Ok(content_splits.nth(1).unwrap().to_string());
    }

    return Ok(content);
}
<|endoftext|>


<commit_before><commit_msg>stat rust version<commit_after><|endoftext|>


<commit_before><commit_msg>Added random weights and biases. Need to control with function. Added pretty print.<commit_after><|endoftext|>


<commit_before><commit_msg>extend view in direction of target<commit_after><|endoftext|>


<commit_before><commit_msg>Added file that will have the sound primitives.<commit_after>/*
 * Sound
 * Sound is handled by libao.
 * When there's a instruction regarding the usage of sound, the interpreter
 * will call a function in this file.
 */
<|endoftext|>


<commit_before><commit_msg>added Audio object<commit_after>/// Represents a audio file
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Audio {
    pub file_id: String,
    pub duration: i64,
    pub performer: Option<String>,
    pub title: Option<String>,
    pub mime_type: Option<String>,
    pub file_size: Option<i64>,
}
<|endoftext|>


<commit_before><commit_msg>addding basic graph implementation in rust<commit_after>enum State {
    WHITE,
    GRAY,
    BLACK,
}

pub trait Traversal {
    fn bfs(&self) {

    }
    fn dfs(&self) {

    }
}

impl Traversal for Graph {
    fn bfs(&self) {

    }
    fn dfs(&self) {

    }
}

use State::*;

pub struct Vertex {
    v_id:u32,
    data:String,
    state:State,
    in_degree:u64,
    out_degree:u64,
}

impl Vertex {
    fn new(v_id:u32,data:&str) -> Self {
        let data = data.to_string();
        Vertex {v_id:v_id,data:data,state:WHITE,in_degree:0,out_degree:0}
    }
}

pub struct Graph {
    v_size:u64,
    v_vec:Vec<Vertex>,
    e_vec:Vec<(Vertex,Vertex)>,
}

impl Graph {
    pub fn new(nodes:u64) -> Self {
        Graph {v_size:0,v_vec:vec![],e_vec:vec![]}
    }

    pub fn add_vertex(&mut self,v:Vertex) {
        self.v_vec.push(v);
    }
}
#[test]
fn graph_init() {
    let mut graph = Graph::new(12);
    let v1 = Vertex::new(0,"Bob");
    let v2 = Vertex::new(1,"Alice");
    let v3 = Vertex::new(2,"Sam");
    let v4 = Vertex::new(3,"Derek");
    graph.add_vertex(v1);
    graph.add_vertex(v2);
    graph.add_vertex(v3);
    graph.add_vertex(v4);
}
<|endoftext|>


<commit_before>use std::fs::{File, OpenOptions};
use std::io;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Display, Path, PathBuf};

use crate::util::errors::CargoResult;
use crate::util::Config;
use anyhow::Context as _;
use cargo_util::paths;
use sys::*;
use termcolor::Color::Cyan;

#[derive(Debug)]
pub struct FileLock {
    f: Option<File>,
    path: PathBuf,
    state: State,
}

#[derive(PartialEq, Debug)]
enum State {
    Unlocked,
    Shared,
    Exclusive,
}

impl FileLock {
    /// Returns the underlying file handle of this lock.
    pub fn file(&self) -> &File {
        self.f.as_ref().unwrap()
    }

    /// Returns the underlying path that this lock points to.
    ///
    /// Note that special care must be taken to ensure that the path is not
    /// referenced outside the lifetime of this lock.
    pub fn path(&self) -> &Path {
        assert_ne!(self.state, State::Unlocked);
        &self.path
    }

    /// Returns the parent path containing this file
    pub fn parent(&self) -> &Path {
        assert_ne!(self.state, State::Unlocked);
        self.path.parent().unwrap()
    }

    /// Removes all sibling files to this locked file.
    ///
    /// This can be useful if a directory is locked with a sentinel file but it
    /// needs to be cleared out as it may be corrupt.
    pub fn remove_siblings(&self) -> CargoResult<()> {
        let path = self.path();
        for entry in path.parent().unwrap().read_dir()? {
            let entry = entry?;
            if Some(&entry.file_name()[..]) == path.file_name() {
                continue;
            }
            let kind = entry.file_type()?;
            if kind.is_dir() {
                paths::remove_dir_all(entry.path())?;
            } else {
                paths::remove_file(entry.path())?;
            }
        }
        Ok(())
    }
}

impl Read for FileLock {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }
}

impl Seek for FileLock {
    fn seek(&mut self, to: SeekFrom) -> io::Result<u64> {
        self.file().seek(to)
    }
}

impl Write for FileLock {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

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

impl Drop for FileLock {
    fn drop(&mut self) {
        if self.state != State::Unlocked {
            if let Some(f) = self.f.take() {
                let _ = unlock(&f);
            }
        }
    }
}

/// A "filesystem" is intended to be a globally shared, hence locked, resource
/// in Cargo.
///
/// The `Path` of a filesystem cannot be learned unless it's done in a locked
/// fashion, and otherwise functions on this structure are prepared to handle
/// concurrent invocations across multiple instances of Cargo.
#[derive(Clone, Debug)]
pub struct Filesystem {
    root: PathBuf,
}

impl Filesystem {
    /// Creates a new filesystem to be rooted at the given path.
    pub fn new(path: PathBuf) -> Filesystem {
        Filesystem { root: path }
    }

    /// Like `Path::join`, creates a new filesystem rooted at this filesystem
    /// joined with the given path.
    pub fn join<T: AsRef<Path>>(&self, other: T) -> Filesystem {
        Filesystem::new(self.root.join(other))
    }

    /// Like `Path::push`, pushes a new path component onto this filesystem.
    pub fn push<T: AsRef<Path>>(&mut self, other: T) {
        self.root.push(other);
    }

    /// Consumes this filesystem and returns the underlying `PathBuf`.
    ///
    /// Note that this is a relatively dangerous operation and should be used
    /// with great caution!.
    pub fn into_path_unlocked(self) -> PathBuf {
        self.root
    }

    /// Returns the underlying `Path`.
    ///
    /// Note that this is a relatively dangerous operation and should be used
    /// with great caution!.
    pub fn as_path_unlocked(&self) -> &Path {
        &self.root
    }

    /// Creates the directory pointed to by this filesystem.
    ///
    /// Handles errors where other Cargo processes are also attempting to
    /// concurrently create this directory.
    pub fn create_dir(&self) -> CargoResult<()> {
        paths::create_dir_all(&self.root)
    }

    /// Returns an adaptor that can be used to print the path of this
    /// filesystem.
    pub fn display(&self) -> Display<'_> {
        self.root.display()
    }

    /// Opens exclusive access to a file, returning the locked version of a
    /// file.
    ///
    /// This function will create a file at `path` if it doesn't already exist
    /// (including intermediate directories), and then it will acquire an
    /// exclusive lock on `path`. If the process must block waiting for the
    /// lock, the `msg` is printed to `config`.
    ///
    /// The returned file can be accessed to look at the path and also has
    /// read/write access to the underlying file.
    pub fn open_rw<P>(&self, path: P, config: &Config, msg: &str) -> CargoResult<FileLock>
    where
        P: AsRef<Path>,
    {
        self.open(
            path.as_ref(),
            OpenOptions::new().read(true).write(true).create(true),
            State::Exclusive,
            config,
            msg,
        )
    }

    /// Opens shared access to a file, returning the locked version of a file.
    ///
    /// This function will fail if `path` doesn't already exist, but if it does
    /// then it will acquire a shared lock on `path`. If the process must block
    /// waiting for the lock, the `msg` is printed to `config`.
    ///
    /// The returned file can be accessed to look at the path and also has read
    /// access to the underlying file. Any writes to the file will return an
    /// error.
    pub fn open_ro<P>(&self, path: P, config: &Config, msg: &str) -> CargoResult<FileLock>
    where
        P: AsRef<Path>,
    {
        self.open(
            path.as_ref(),
            OpenOptions::new().read(true),
            State::Shared,
            config,
            msg,
        )
    }

    fn open(
        &self,
        path: &Path,
        opts: &OpenOptions,
        state: State,
        config: &Config,
        msg: &str,
    ) -> CargoResult<FileLock> {
        let path = self.root.join(path);

        // If we want an exclusive lock then if we fail because of NotFound it's
        // likely because an intermediate directory didn't exist, so try to
        // create the directory and then continue.
        let f = opts
            .open(&path)
            .or_else(|e| {
                if e.kind() == io::ErrorKind::NotFound && state == State::Exclusive {
                    paths::create_dir_all(path.parent().unwrap())?;
                    Ok(opts.open(&path)?)
                } else {
                    Err(anyhow::Error::from(e))
                }
            })
            .with_context(|| format!("failed to open: {}", path.display()))?;
        match state {
            State::Exclusive => {
                acquire(config, msg, &path, &|| try_lock_exclusive(&f), &|| {
                    lock_exclusive(&f)
                })?;
            }
            State::Shared => {
                acquire(config, msg, &path, &|| try_lock_shared(&f), &|| {
                    lock_shared(&f)
                })?;
            }
            State::Unlocked => {}
        }
        Ok(FileLock {
            f: Some(f),
            path,
            state,
        })
    }
}

impl PartialEq<Path> for Filesystem {
    fn eq(&self, other: &Path) -> bool {
        self.root == other
    }
}

impl PartialEq<Filesystem> for Path {
    fn eq(&self, other: &Filesystem) -> bool {
        self == other.root
    }
}

/// Acquires a lock on a file in a "nice" manner.
///
/// Almost all long-running blocking actions in Cargo have a status message
/// associated with them as we're not sure how long they'll take. Whenever a
/// conflicted file lock happens, this is the case (we're not sure when the lock
/// will be released).
///
/// This function will acquire the lock on a `path`, printing out a nice message
/// to the console if we have to wait for it. It will first attempt to use `try`
/// to acquire a lock on the crate, and in the case of contention it will emit a
/// status message based on `msg` to `config`'s shell, and then use `block` to
/// block waiting to acquire a lock.
///
/// Returns an error if the lock could not be acquired or if any error other
/// than a contention error happens.
fn acquire(
    config: &Config,
    msg: &str,
    path: &Path,
    lock_try: &dyn Fn() -> io::Result<()>,
    lock_block: &dyn Fn() -> io::Result<()>,
) -> CargoResult<()> {
    // File locking on Unix is currently implemented via `flock`, which is known
    // to be broken on NFS. We could in theory just ignore errors that happen on
    // NFS, but apparently the failure mode [1] for `flock` on NFS is **blocking
    // forever**, even if the "non-blocking" flag is passed!
    //
    // As a result, we just skip all file locks entirely on NFS mounts. That
    // should avoid calling any `flock` functions at all, and it wouldn't work
    // there anyway.
    //
    // [1]: https://github.com/rust-lang/cargo/issues/2615
    if is_on_nfs_mount(path) {
        return Ok(());
    }

    match lock_try() {
        Ok(()) => return Ok(()),

        // In addition to ignoring NFS which is commonly not working we also
        // just ignore locking on filesystems that look like they don't
        // implement file locking.
        Err(e) if error_unsupported(&e) => return Ok(()),

        Err(e) => {
            if !error_contended(&e) {
                let e = anyhow::Error::from(e);
                let cx = format!("failed to lock file: {}", path.display());
                return Err(e.context(cx));
            }
        }
    }
    let msg = format!("waiting for file lock on {}", msg);
    config.shell().status_with_color("Blocking", &msg, Cyan)?;

    lock_block().with_context(|| format!("failed to lock file: {}", path.display()))?;
    return Ok(());

    #[cfg(all(target_os = "linux", not(target_env = "musl")))]
    fn is_on_nfs_mount(path: &Path) -> bool {
        use std::ffi::CString;
        use std::mem;
        use std::os::unix::prelude::*;

        let path = match CString::new(path.as_os_str().as_bytes()) {
            Ok(path) => path,
            Err(_) => return false,
        };

        unsafe {
            let mut buf: libc::statfs = mem::zeroed();
            let r = libc::statfs(path.as_ptr(), &mut buf);

            r == 0 && buf.f_type as u32 == libc::NFS_SUPER_MAGIC as u32
        }
    }

    #[cfg(any(not(target_os = "linux"), target_env = "musl"))]
    fn is_on_nfs_mount(_path: &Path) -> bool {
        false
    }
}

#[cfg(unix)]
mod sys {
    use std::fs::File;
    use std::io::{Error, Result};
    use std::os::unix::io::AsRawFd;

    pub(super) fn lock_shared(file: &File) -> Result<()> {
        flock(file, libc::LOCK_SH)
    }

    pub(super) fn lock_exclusive(file: &File) -> Result<()> {
        flock(file, libc::LOCK_EX)
    }

    pub(super) fn try_lock_shared(file: &File) -> Result<()> {
        flock(file, libc::LOCK_SH | libc::LOCK_NB)
    }

    pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
        flock(file, libc::LOCK_EX | libc::LOCK_NB)
    }

    pub(super) fn unlock(file: &File) -> Result<()> {
        flock(file, libc::LOCK_UN)
    }

    pub(super) fn error_contended(err: &Error) -> bool {
        err.raw_os_error().map_or(false, |x| x == libc::EWOULDBLOCK)
    }

    pub(super) fn error_unsupported(err: &Error) -> bool {
        match err.raw_os_error() {
            // Unfortunately, depending on the target, these may or may not be the same.
            // For targets in which they are the same, the duplicate pattern causes a warning.
            #[allow(unreachable_patterns)]
            Some(libc::ENOTSUP | libc::EOPNOTSUPP) => true,
            #[cfg(any(target_os = "linux", target_os = "android"))]
            Some(libc::ENOSYS) => true,
            _ => false,
        }
    }

    #[cfg(not(target_os = "solaris"))]
    fn flock(file: &File, flag: libc::c_int) -> Result<()> {
        let ret = unsafe { libc::flock(file.as_raw_fd(), flag) };
        if ret < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(())
        }
    }

    #[cfg(target_os = "solaris")]
    fn flock(file: &File, flag: libc::c_int) -> Result<()> {
        // Solaris lacks flock(), so simply succeed with a no-op
        Ok(())
    }
}

#[cfg(windows)]
mod sys {
    use std::fs::File;
    use std::io::{Error, Result};
    use std::mem;
    use std::os::windows::io::AsRawHandle;

    use winapi::shared::minwindef::DWORD;
    use winapi::shared::winerror::{ERROR_INVALID_FUNCTION, ERROR_LOCK_VIOLATION};
    use winapi::um::fileapi::{LockFileEx, UnlockFile};
    use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY};

    pub(super) fn lock_shared(file: &File) -> Result<()> {
        lock_file(file, 0)
    }

    pub(super) fn lock_exclusive(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_EXCLUSIVE_LOCK)
    }

    pub(super) fn try_lock_shared(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_FAIL_IMMEDIATELY)
    }

    pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY)
    }

    pub(super) fn error_contended(err: &Error) -> bool {
        err.raw_os_error()
            .map_or(false, |x| x == ERROR_LOCK_VIOLATION as i32)
    }

    pub(super) fn error_unsupported(err: &Error) -> bool {
        err.raw_os_error()
            .map_or(false, |x| x == ERROR_INVALID_FUNCTION as i32)
    }

    pub(super) fn unlock(file: &File) -> Result<()> {
        unsafe {
            let ret = UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
            if ret == 0 {
                Err(Error::last_os_error())
            } else {
                Ok(())
            }
        }
    }

    fn lock_file(file: &File, flags: DWORD) -> Result<()> {
        unsafe {
            let mut overlapped = mem::zeroed();
            let ret = LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
            if ret == 0 {
                Err(Error::last_os_error())
            } else {
                Ok(())
            }
        }
    }
}
<commit_msg>No longer gate unsupported file locking behind Linux as OS<commit_after>use std::fs::{File, OpenOptions};
use std::io;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Display, Path, PathBuf};

use crate::util::errors::CargoResult;
use crate::util::Config;
use anyhow::Context as _;
use cargo_util::paths;
use sys::*;
use termcolor::Color::Cyan;

#[derive(Debug)]
pub struct FileLock {
    f: Option<File>,
    path: PathBuf,
    state: State,
}

#[derive(PartialEq, Debug)]
enum State {
    Unlocked,
    Shared,
    Exclusive,
}

impl FileLock {
    /// Returns the underlying file handle of this lock.
    pub fn file(&self) -> &File {
        self.f.as_ref().unwrap()
    }

    /// Returns the underlying path that this lock points to.
    ///
    /// Note that special care must be taken to ensure that the path is not
    /// referenced outside the lifetime of this lock.
    pub fn path(&self) -> &Path {
        assert_ne!(self.state, State::Unlocked);
        &self.path
    }

    /// Returns the parent path containing this file
    pub fn parent(&self) -> &Path {
        assert_ne!(self.state, State::Unlocked);
        self.path.parent().unwrap()
    }

    /// Removes all sibling files to this locked file.
    ///
    /// This can be useful if a directory is locked with a sentinel file but it
    /// needs to be cleared out as it may be corrupt.
    pub fn remove_siblings(&self) -> CargoResult<()> {
        let path = self.path();
        for entry in path.parent().unwrap().read_dir()? {
            let entry = entry?;
            if Some(&entry.file_name()[..]) == path.file_name() {
                continue;
            }
            let kind = entry.file_type()?;
            if kind.is_dir() {
                paths::remove_dir_all(entry.path())?;
            } else {
                paths::remove_file(entry.path())?;
            }
        }
        Ok(())
    }
}

impl Read for FileLock {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.file().read(buf)
    }
}

impl Seek for FileLock {
    fn seek(&mut self, to: SeekFrom) -> io::Result<u64> {
        self.file().seek(to)
    }
}

impl Write for FileLock {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.file().write(buf)
    }

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

impl Drop for FileLock {
    fn drop(&mut self) {
        if self.state != State::Unlocked {
            if let Some(f) = self.f.take() {
                let _ = unlock(&f);
            }
        }
    }
}

/// A "filesystem" is intended to be a globally shared, hence locked, resource
/// in Cargo.
///
/// The `Path` of a filesystem cannot be learned unless it's done in a locked
/// fashion, and otherwise functions on this structure are prepared to handle
/// concurrent invocations across multiple instances of Cargo.
#[derive(Clone, Debug)]
pub struct Filesystem {
    root: PathBuf,
}

impl Filesystem {
    /// Creates a new filesystem to be rooted at the given path.
    pub fn new(path: PathBuf) -> Filesystem {
        Filesystem { root: path }
    }

    /// Like `Path::join`, creates a new filesystem rooted at this filesystem
    /// joined with the given path.
    pub fn join<T: AsRef<Path>>(&self, other: T) -> Filesystem {
        Filesystem::new(self.root.join(other))
    }

    /// Like `Path::push`, pushes a new path component onto this filesystem.
    pub fn push<T: AsRef<Path>>(&mut self, other: T) {
        self.root.push(other);
    }

    /// Consumes this filesystem and returns the underlying `PathBuf`.
    ///
    /// Note that this is a relatively dangerous operation and should be used
    /// with great caution!.
    pub fn into_path_unlocked(self) -> PathBuf {
        self.root
    }

    /// Returns the underlying `Path`.
    ///
    /// Note that this is a relatively dangerous operation and should be used
    /// with great caution!.
    pub fn as_path_unlocked(&self) -> &Path {
        &self.root
    }

    /// Creates the directory pointed to by this filesystem.
    ///
    /// Handles errors where other Cargo processes are also attempting to
    /// concurrently create this directory.
    pub fn create_dir(&self) -> CargoResult<()> {
        paths::create_dir_all(&self.root)
    }

    /// Returns an adaptor that can be used to print the path of this
    /// filesystem.
    pub fn display(&self) -> Display<'_> {
        self.root.display()
    }

    /// Opens exclusive access to a file, returning the locked version of a
    /// file.
    ///
    /// This function will create a file at `path` if it doesn't already exist
    /// (including intermediate directories), and then it will acquire an
    /// exclusive lock on `path`. If the process must block waiting for the
    /// lock, the `msg` is printed to `config`.
    ///
    /// The returned file can be accessed to look at the path and also has
    /// read/write access to the underlying file.
    pub fn open_rw<P>(&self, path: P, config: &Config, msg: &str) -> CargoResult<FileLock>
    where
        P: AsRef<Path>,
    {
        self.open(
            path.as_ref(),
            OpenOptions::new().read(true).write(true).create(true),
            State::Exclusive,
            config,
            msg,
        )
    }

    /// Opens shared access to a file, returning the locked version of a file.
    ///
    /// This function will fail if `path` doesn't already exist, but if it does
    /// then it will acquire a shared lock on `path`. If the process must block
    /// waiting for the lock, the `msg` is printed to `config`.
    ///
    /// The returned file can be accessed to look at the path and also has read
    /// access to the underlying file. Any writes to the file will return an
    /// error.
    pub fn open_ro<P>(&self, path: P, config: &Config, msg: &str) -> CargoResult<FileLock>
    where
        P: AsRef<Path>,
    {
        self.open(
            path.as_ref(),
            OpenOptions::new().read(true),
            State::Shared,
            config,
            msg,
        )
    }

    fn open(
        &self,
        path: &Path,
        opts: &OpenOptions,
        state: State,
        config: &Config,
        msg: &str,
    ) -> CargoResult<FileLock> {
        let path = self.root.join(path);

        // If we want an exclusive lock then if we fail because of NotFound it's
        // likely because an intermediate directory didn't exist, so try to
        // create the directory and then continue.
        let f = opts
            .open(&path)
            .or_else(|e| {
                if e.kind() == io::ErrorKind::NotFound && state == State::Exclusive {
                    paths::create_dir_all(path.parent().unwrap())?;
                    Ok(opts.open(&path)?)
                } else {
                    Err(anyhow::Error::from(e))
                }
            })
            .with_context(|| format!("failed to open: {}", path.display()))?;
        match state {
            State::Exclusive => {
                acquire(config, msg, &path, &|| try_lock_exclusive(&f), &|| {
                    lock_exclusive(&f)
                })?;
            }
            State::Shared => {
                acquire(config, msg, &path, &|| try_lock_shared(&f), &|| {
                    lock_shared(&f)
                })?;
            }
            State::Unlocked => {}
        }
        Ok(FileLock {
            f: Some(f),
            path,
            state,
        })
    }
}

impl PartialEq<Path> for Filesystem {
    fn eq(&self, other: &Path) -> bool {
        self.root == other
    }
}

impl PartialEq<Filesystem> for Path {
    fn eq(&self, other: &Filesystem) -> bool {
        self == other.root
    }
}

/// Acquires a lock on a file in a "nice" manner.
///
/// Almost all long-running blocking actions in Cargo have a status message
/// associated with them as we're not sure how long they'll take. Whenever a
/// conflicted file lock happens, this is the case (we're not sure when the lock
/// will be released).
///
/// This function will acquire the lock on a `path`, printing out a nice message
/// to the console if we have to wait for it. It will first attempt to use `try`
/// to acquire a lock on the crate, and in the case of contention it will emit a
/// status message based on `msg` to `config`'s shell, and then use `block` to
/// block waiting to acquire a lock.
///
/// Returns an error if the lock could not be acquired or if any error other
/// than a contention error happens.
fn acquire(
    config: &Config,
    msg: &str,
    path: &Path,
    lock_try: &dyn Fn() -> io::Result<()>,
    lock_block: &dyn Fn() -> io::Result<()>,
) -> CargoResult<()> {
    // File locking on Unix is currently implemented via `flock`, which is known
    // to be broken on NFS. We could in theory just ignore errors that happen on
    // NFS, but apparently the failure mode [1] for `flock` on NFS is **blocking
    // forever**, even if the "non-blocking" flag is passed!
    //
    // As a result, we just skip all file locks entirely on NFS mounts. That
    // should avoid calling any `flock` functions at all, and it wouldn't work
    // there anyway.
    //
    // [1]: https://github.com/rust-lang/cargo/issues/2615
    if is_on_nfs_mount(path) {
        return Ok(());
    }

    match lock_try() {
        Ok(()) => return Ok(()),

        // In addition to ignoring NFS which is commonly not working we also
        // just ignore locking on filesystems that look like they don't
        // implement file locking.
        Err(e) if error_unsupported(&e) => return Ok(()),

        Err(e) => {
            if !error_contended(&e) {
                let e = anyhow::Error::from(e);
                let cx = format!("failed to lock file: {}", path.display());
                return Err(e.context(cx));
            }
        }
    }
    let msg = format!("waiting for file lock on {}", msg);
    config.shell().status_with_color("Blocking", &msg, Cyan)?;

    lock_block().with_context(|| format!("failed to lock file: {}", path.display()))?;
    return Ok(());

    #[cfg(all(target_os = "linux", not(target_env = "musl")))]
    fn is_on_nfs_mount(path: &Path) -> bool {
        use std::ffi::CString;
        use std::mem;
        use std::os::unix::prelude::*;

        let path = match CString::new(path.as_os_str().as_bytes()) {
            Ok(path) => path,
            Err(_) => return false,
        };

        unsafe {
            let mut buf: libc::statfs = mem::zeroed();
            let r = libc::statfs(path.as_ptr(), &mut buf);

            r == 0 && buf.f_type as u32 == libc::NFS_SUPER_MAGIC as u32
        }
    }

    #[cfg(any(not(target_os = "linux"), target_env = "musl"))]
    fn is_on_nfs_mount(_path: &Path) -> bool {
        false
    }
}

#[cfg(unix)]
mod sys {
    use std::fs::File;
    use std::io::{Error, Result};
    use std::os::unix::io::AsRawFd;

    pub(super) fn lock_shared(file: &File) -> Result<()> {
        flock(file, libc::LOCK_SH)
    }

    pub(super) fn lock_exclusive(file: &File) -> Result<()> {
        flock(file, libc::LOCK_EX)
    }

    pub(super) fn try_lock_shared(file: &File) -> Result<()> {
        flock(file, libc::LOCK_SH | libc::LOCK_NB)
    }

    pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
        flock(file, libc::LOCK_EX | libc::LOCK_NB)
    }

    pub(super) fn unlock(file: &File) -> Result<()> {
        flock(file, libc::LOCK_UN)
    }

    pub(super) fn error_contended(err: &Error) -> bool {
        err.raw_os_error().map_or(false, |x| x == libc::EWOULDBLOCK)
    }

    pub(super) fn error_unsupported(err: &Error) -> bool {
        match err.raw_os_error() {
            // Unfortunately, depending on the target, these may or may not be the same.
            // For targets in which they are the same, the duplicate pattern causes a warning.
            #[allow(unreachable_patterns)]
            Some(libc::ENOTSUP | libc::EOPNOTSUPP) => true,
            Some(libc::ENOSYS) => true,
            _ => false,
        }
    }

    #[cfg(not(target_os = "solaris"))]
    fn flock(file: &File, flag: libc::c_int) -> Result<()> {
        let ret = unsafe { libc::flock(file.as_raw_fd(), flag) };
        if ret < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(())
        }
    }

    #[cfg(target_os = "solaris")]
    fn flock(file: &File, flag: libc::c_int) -> Result<()> {
        // Solaris lacks flock(), so simply succeed with a no-op
        Ok(())
    }
}

#[cfg(windows)]
mod sys {
    use std::fs::File;
    use std::io::{Error, Result};
    use std::mem;
    use std::os::windows::io::AsRawHandle;

    use winapi::shared::minwindef::DWORD;
    use winapi::shared::winerror::{ERROR_INVALID_FUNCTION, ERROR_LOCK_VIOLATION};
    use winapi::um::fileapi::{LockFileEx, UnlockFile};
    use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY};

    pub(super) fn lock_shared(file: &File) -> Result<()> {
        lock_file(file, 0)
    }

    pub(super) fn lock_exclusive(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_EXCLUSIVE_LOCK)
    }

    pub(super) fn try_lock_shared(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_FAIL_IMMEDIATELY)
    }

    pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
        lock_file(file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY)
    }

    pub(super) fn error_contended(err: &Error) -> bool {
        err.raw_os_error()
            .map_or(false, |x| x == ERROR_LOCK_VIOLATION as i32)
    }

    pub(super) fn error_unsupported(err: &Error) -> bool {
        err.raw_os_error()
            .map_or(false, |x| x == ERROR_INVALID_FUNCTION as i32)
    }

    pub(super) fn unlock(file: &File) -> Result<()> {
        unsafe {
            let ret = UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
            if ret == 0 {
                Err(Error::last_os_error())
            } else {
                Ok(())
            }
        }
    }

    fn lock_file(file: &File, flags: DWORD) -> Result<()> {
        unsafe {
            let mut overlapped = mem::zeroed();
            let ret = LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
            if ret == 0 {
                Err(Error::last_os_error())
            } else {
                Ok(())
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Change target directory of completions to target/<commit_after><|endoftext|>


<commit_before><commit_msg>no ; after match expression<commit_after><|endoftext|>


<commit_before><commit_msg>build: write pkginfo to build dir, fix builddate<commit_after><|endoftext|>


<commit_before><commit_msg>NamedGetter completed and fixed issues<commit_after><|endoftext|>


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

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::URLSearchParamsBinding;
use dom::bindings::codegen::Bindings::URLSearchParamsBinding::URLSearchParamsMethods;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eURLSearchParams, eString};
use dom::bindings::error::{Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};

use util::str::DOMString;

use encoding::all::UTF_8;
use encoding::types::{EncodingRef, EncoderTrap};

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::fmt::radix;
use std::ascii::OwnedAsciiExt;

#[dom_struct]
pub struct URLSearchParams {
    reflector_: Reflector,
    data: DOMRefCell<HashMap<DOMString, Vec<DOMString>>>,
}

impl URLSearchParams {
    fn new_inherited() -> URLSearchParams {
        URLSearchParams {
            reflector_: Reflector::new(),
            data: DOMRefCell::new(HashMap::new()),
        }
    }

    pub fn new(global: GlobalRef) -> Temporary<URLSearchParams> {
        reflect_dom_object(box URLSearchParams::new_inherited(), global, URLSearchParamsBinding::Wrap)
    }

    pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) -> Fallible<Temporary<URLSearchParams>> {
        let usp = URLSearchParams::new(global).root();
        match init {
            Some(eString(_s)) => {
                // XXXManishearth we need to parse the input here
                // http://url.spec.whatwg.org/#concept-urlencoded-parser
                // We can use rust-url's implementation here:
                // https://github.com/SimonSapin/rust-url/blob/master/form_urlencoded.rs#L29
            },
            Some(eURLSearchParams(u)) => {
                let u = u.root();
                let usp = usp.r();
                let mut map = usp.data.borrow_mut();
                // FIXME(https://github.com/rust-lang/rust/issues/23338)
                let r = u.r();
                let data = r.data.borrow();
                *map = data.clone();
            },
            None => {}
        }
        Ok(Temporary::from_rooted(usp.r()))
    }
}

impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> {
    fn Append(self, name: DOMString, value: DOMString) {
        let mut data = self.data.borrow_mut();

        match data.entry(name) {
            Occupied(entry) => entry.into_mut().push(value),
            Vacant(entry) => {
                entry.insert(vec!(value));
            }
        }

        self.update_steps();
    }

    fn Delete(self, name: DOMString) {
        self.data.borrow_mut().remove(&name);
        self.update_steps();
    }

    fn Get(self, name: DOMString) -> Option<DOMString> {
        // FIXME(https://github.com/rust-lang/rust/issues/23338)
        let data = self.data.borrow();
        data.get(&name).map(|v| v[0].clone())
    }

    fn Has(self, name: DOMString) -> bool {
        // FIXME(https://github.com/rust-lang/rust/issues/23338)
        let data = self.data.borrow();
        data.contains_key(&name)
    }

    fn Set(self, name: DOMString, value: DOMString) {
        self.data.borrow_mut().insert(name, vec!(value));
        self.update_steps();
    }
}

pub trait URLSearchParamsHelpers {
    fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8>;
    fn update_steps(&self);
}

impl URLSearchParamsHelpers for URLSearchParams {
    fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8> {
        // http://url.spec.whatwg.org/#concept-urlencoded-serializer
        fn serialize_string(value: &DOMString, encoding: EncodingRef) -> Vec<u8> {
            // http://url.spec.whatwg.org/#concept-urlencoded-byte-serializer

            let value = value.as_slice();
            // XXXManishearth should this be a strict encoding? Can unwrap()ing the result fail?
            let value = encoding.encode(value, EncoderTrap::Replace).unwrap();
            let mut buf = vec!();
            for i in value.iter() {
                let append = match *i {
                    0x20 => vec!(0x2B),
                    0x2A | 0x2D | 0x2E |
                    0x30 ... 0x39 | 0x41 ... 0x5A |
                    0x5F | 0x61...0x7A => vec!(*i),
                    a => {
                        // http://url.spec.whatwg.org/#percent-encode
                        let mut encoded = vec!(0x25); // %
                        let s = format!("{}", radix(a, 16)).into_ascii_uppercase();
                        let bytes = s.as_bytes();
                        encoded.push_all(bytes);
                        encoded
                    }
                };
                buf.push_all(append.as_slice());
            }
            buf
        }
        let encoding = encoding.unwrap_or(UTF_8 as EncodingRef);
        let mut buf = vec!();
        let mut first_pair = true;
        for (k, v) in self.data.borrow().iter() {
            let name = serialize_string(k, encoding);
            for val in v.iter() {
                let value = serialize_string(val, encoding);
                if first_pair {
                    first_pair = false;
                } else {
                    buf.push(0x26); // &
                }
                buf.push_all(name.as_slice());
                buf.push(0x3D); // =
                buf.push_all(value.as_slice())
            }
        }
        buf
    }

    fn update_steps(&self) {
        // XXXManishearth Implement this when the URL interface is implemented
        // http://url.spec.whatwg.org/#concept-uq-update
    }
}
<commit_msg>auto merge of #5319 : frewsxcv/servo/urlsearchparams, r=Ms2ger<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::URLSearchParamsBinding;
use dom::bindings::codegen::Bindings::URLSearchParamsBinding::URLSearchParamsMethods;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eURLSearchParams, eString};
use dom::bindings::error::{Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};

use util::str::DOMString;

use encoding::all::UTF_8;
use encoding::types::{EncodingRef, EncoderTrap};

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::fmt::radix;
use std::ascii::OwnedAsciiExt;

#[dom_struct]
pub struct URLSearchParams {
    reflector_: Reflector,
    data: DOMRefCell<HashMap<DOMString, Vec<DOMString>>>,
}

impl URLSearchParams {
    fn new_inherited() -> URLSearchParams {
        URLSearchParams {
            reflector_: Reflector::new(),
            data: DOMRefCell::new(HashMap::new()),
        }
    }

    pub fn new(global: GlobalRef) -> Temporary<URLSearchParams> {
        reflect_dom_object(box URLSearchParams::new_inherited(), global,
                           URLSearchParamsBinding::Wrap)
    }

    pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) ->
                       Fallible<Temporary<URLSearchParams>> {
        let usp = URLSearchParams::new(global).root();
        match init {
            Some(eString(_s)) => {
                // XXXManishearth we need to parse the input here
                // http://url.spec.whatwg.org/#concept-urlencoded-parser
                // We can use rust-url's implementation here:
                // https://github.com/SimonSapin/rust-url/blob/master/form_urlencoded.rs#L29
            },
            Some(eURLSearchParams(u)) => {
                let u = u.root();
                let usp = usp.r();
                let mut map = usp.data.borrow_mut();
                // FIXME(https://github.com/rust-lang/rust/issues/23338)
                let r = u.r();
                let data = r.data.borrow();
                *map = data.clone();
            },
            None => {}
        }
        Ok(Temporary::from_rooted(usp.r()))
    }
}

impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> {
    fn Append(self, name: DOMString, value: DOMString) {
        let mut data = self.data.borrow_mut();

        match data.entry(name) {
            Occupied(entry) => entry.into_mut().push(value),
            Vacant(entry) => {
                entry.insert(vec!(value));
            }
        }

        self.update_steps();
    }

    fn Delete(self, name: DOMString) {
        self.data.borrow_mut().remove(&name);
        self.update_steps();
    }

    fn Get(self, name: DOMString) -> Option<DOMString> {
        // FIXME(https://github.com/rust-lang/rust/issues/23338)
        let data = self.data.borrow();
        data.get(&name).map(|v| v[0].clone())
    }

    fn Has(self, name: DOMString) -> bool {
        // FIXME(https://github.com/rust-lang/rust/issues/23338)
        let data = self.data.borrow();
        data.contains_key(&name)
    }

    fn Set(self, name: DOMString, value: DOMString) {
        self.data.borrow_mut().insert(name, vec!(value));
        self.update_steps();
    }
}

pub trait URLSearchParamsHelpers {
    fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8>;
    fn update_steps(&self);
}

impl URLSearchParamsHelpers for URLSearchParams {
    fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8> {
        // http://url.spec.whatwg.org/#concept-urlencoded-serializer
        fn serialize_string(value: &DOMString, encoding: EncodingRef) -> Vec<u8> {
            // http://url.spec.whatwg.org/#concept-urlencoded-byte-serializer

            let value = value.as_slice();
            // XXXManishearth should this be a strict encoding? Can unwrap()ing the result fail?
            let value = encoding.encode(value, EncoderTrap::Replace).unwrap();

            // Step 1.
            let mut buf = vec!();

            // Step 2.
            for i in &value {
                let append = match *i {
                    // Convert spaces:
                    // ' ' => '+'
                    0x20 => vec!(0x2B),

                    // Retain the following characters:
                    // '*', '-', '.', '0'...'9', 'A'...'Z', '_', 'a'...'z'
                    0x2A | 0x2D | 0x2E | 0x30...0x39 |
                        0x41...0x5A | 0x5F | 0x61...0x7A => vec!(*i),

                    // Encode everything else using 'percented-encoded bytes'
                    // http://url.spec.whatwg.org/#percent-encode
                    a => {
                        let mut encoded = vec!(0x25); // %
                        let s = format!("{}", radix(a, 16)).into_ascii_uppercase();
                        let bytes = s.as_bytes();
                        encoded.push_all(bytes);
                        encoded
                    }
                };
                buf.push_all(&append);
            }

            // Step 3.
            buf
        }
        let encoding = encoding.unwrap_or(UTF_8 as EncodingRef);
        let mut buf = vec!();
        let mut first_pair = true;
        for (k, v) in self.data.borrow().iter() {
            let name = serialize_string(k, encoding);
            for val in v {
                let value = serialize_string(val, encoding);
                if first_pair {
                    first_pair = false;
                } else {
                    buf.push(0x26); // &
                }
                buf.push_all(&name);
                buf.push(0x3D); // =
                buf.push_all(&value)
            }
        }
        buf
    }

    fn update_steps(&self) {
        // XXXManishearth Implement this when the URL interface is implemented
        // http://url.spec.whatwg.org/#concept-uq-update
    }
}
<|endoftext|>


<commit_before><commit_msg>core: derive additional traits for exposed types<commit_after><|endoftext|>


<commit_before><commit_msg>retag<commit_after><|endoftext|>


<commit_before><commit_msg>Fix one clippy warning.<commit_after><|endoftext|>


<commit_before><commit_msg> change to make all tests run<commit_after><|endoftext|>


<commit_before><commit_msg>fix(doctest): work around lack of `Copy`ability in stdlib structs<commit_after><|endoftext|>


<commit_before><commit_msg>Iter & IterMut<commit_after><|endoftext|>


<commit_before>use rustc_serialize::json;
use rustc_serialize::base64::FromBase64;
use error::Error;

#[derive(RustcDecodable, RustcEncodable)]
pub struct Header {
    pub typ: String,
    pub alg: Option<String>,
}

impl Header {
    pub fn parse(raw: &str) -> Result<Header, Error> {
        let data = try!(raw.from_base64());
        let s = try!(String::from_utf8(data));
        let header = try!(json::decode(&*s));

        Ok(header)
    }
}
<commit_msg>Add test for header<commit_after>use rustc_serialize::json;
use rustc_serialize::base64::FromBase64;
use error::Error;

#[derive(RustcDecodable, RustcEncodable)]
pub struct Header {
    pub typ: String,
    pub alg: Option<String>,
}

impl Header {
    pub fn parse(raw: &str) -> Result<Header, Error> {
        let data = try!(raw.from_base64());
        let s = try!(String::from_utf8(data));
        let header = try!(json::decode(&*s));

        Ok(header)
    }
}

#[cfg(test)]
mod tests {
    use header::Header;

    #[test]
    fn parse() {
        let enc = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
        let header = Header::parse(enc).unwrap();

        assert_eq!(header.typ, "JWT");
        assert_eq!(header.alg.unwrap(), "HS256");
    }
}
<|endoftext|>


<commit_before><commit_msg>Refactor Chunk debug to be procedural<commit_after><|endoftext|>


<commit_before><commit_msg>Adds Rust Problem 8<commit_after>/// Problem 8
/// The four adjacent digits in the 1000-digit number that have the greatest
/// product are 9 × 9 × 8 × 9 = 5832.
///
/// 73167176531330624919225119674426574742355349194934
/// 96983520312774506326239578318016984801869478851843
/// 85861560789112949495459501737958331952853208805511
/// 12540698747158523863050715693290963295227443043557
/// 66896648950445244523161731856403098711121722383113
/// 62229893423380308135336276614282806444486645238749
/// 30358907296290491560440772390713810515859307960866
/// 70172427121883998797908792274921901699720888093776
/// 65727333001053367881220235421809751254540594752243
/// 52584907711670556013604839586446706324415722155397
/// 53697817977846174064955149290862569321978468622482
/// 83972241375657056057490261407972968652414535100474
/// 82166370484403199890008895243450658541227588666881
/// 16427171479924442928230863465674813919123162824586
/// 17866458359124566529476545682848912883142607690042
/// 24219022671055626321111109370544217506941658960408
/// 07198403850962455444362981230987879927244284909188
/// 84580156166097919133875499200524063689912560717606
/// 05886116467109405077541002256983155200055935729725
/// 71636269561882670428252483600823257530420752963450
///
/// Find the thirteen adjacent digits in the 1000-digit number that have the
/// greatest product. What is the value of this product?
fn main() {
    // How many adjacent digits to check?
    let adj: usize = 13;
    let num: String = "73167176531330624919225119674426574742355349194934\
                    96983520312774506326239578318016984801869478851843\
                    85861560789112949495459501737958331952853208805511\
                    12540698747158523863050715693290963295227443043557\
                    66896648950445244523161731856403098711121722383113\
                    62229893423380308135336276614282806444486645238749\
                    30358907296290491560440772390713810515859307960866\
                    70172427121883998797908792274921901699720888093776\
                    65727333001053367881220235421809751254540594752243\
                    52584907711670556013604839586446706324415722155397\
                    53697817977846174064955149290862569321978468622482\
                    83972241375657056057490261407972968652414535100474\
                    82166370484403199890008895243450658541227588666881\
                    16427171479924442928230863465674813919123162824586\
                    17866458359124566529476545682848912883142607690042\
                    24219022671055626321111109370544217506941658960408\
                    07198403850962455444362981230987879927244284909188\
                    84580156166097919133875499200524063689912560717606\
                    05886116467109405077541002256983155200055935729725\
                    71636269561882670428252483600823257530420752963450".to_string();
    // let mut digits: Vec<u8> = Vec::new();

    // for c in num.chars() {
    //     digits.push(try!(c.to_digit(10)))
    // }

    let digits: Vec<u8> = num.chars()
        .map(|c| c.to_digit(10).unwrap() as u8)
        .collect();

    let mut window: Vec<u8> = Vec::new();
    let mut max: u64 = 0;
    let mut max_window: Vec<u8> = vec![0u8; adj];

    for d in digits {
        if window.len() < adj {
            window.push(d);
        } else {
            let mut mul: u64 = 1;
            for v in &window {
                mul *= *v as u64;
            }
            if mul > max {
                max = mul;
                max_window.clone_from_slice(&window);
            }

            window.push(d);
            window = window.split_off(1);
        }
    }

    print!("Answer: {} [digits: ", max);
    for d in max_window {
        print!("{}", d);
    }
    print!("]\n");
}<|endoftext|>


<commit_before>use orbclient;
use super::super::geometry;
use std;

/// Draw a triangle, from 9 floats representing vertice coordinates
#[allow(dead_code)]
pub fn triangle_p(x1: f32, y1: f32, z1: f32,
                  x2: f32, y2: f32, z2: f32,
                  x3: f32, y3: f32, z3: f32,
                  color: orbclient::Color, window: &mut orbclient::window::Window) {
    use super::{perpective, screen};
    use std::cmp::{min, max};

    // Calculate perspective for points.
    let (x1, y1) = perpective(x1, y1, z1);
    let (x2, y2) = perpective(x2, y2, z2);
    let (x3, y3) = perpective(x3, y3, z3);

    let scr_width  =  window.width() as i32;
    let scr_height = window.height() as i32;

    // Change f32 points into drawable i32, based on screen width,
    let (x1, y1) = screen(x1, y1, scr_width, scr_height);
    let (x2, y2) = screen(x2, y2, scr_width, scr_height);
    let (x3, y3) = screen(x3, y3, scr_width, scr_height);

    let x_low = min(x1, min(x2, x3));
    let x_max = max(x1, max(x2, x3));
    let y_low = min(y1, min(y2, y3));
    let y_max = max(y1, max(y2, y3));

    {
        let x1 = x1 as f32;
        let y1 = y1 as f32;
        let x2 = x2 as f32;
        let y2 = y2 as f32;
        let x3 = x3 as f32;
        let y3 = y3 as f32;

        for x in x_low..x_max {
            for y in y_low..y_max {
                    let mut alpha: f32;
                    let mut beta: f32;
                    let mut gamma: f32;

                    let x = x as f32;
                    let y = y as f32;

                    alpha = ((y2 - y3)*(x - x3) + (x3 - x2)*(y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3));
                    beta = ((y3 - y1)*(x - x3) + (x1 - x3)*(y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3));
                    gamma = 1.0 - alpha - beta;

                    if alpha > 0.0 && beta > 0.0 && gamma > 0.0 {
                        window.pixel(x as i32, y as i32, color);
                    }
            }
        }
    }

    window.line(x1, y1, x2, y2, color);
    window.line(x2, y2, x3, y3, color);
    window.line(x3, y3, x1, y1, color);
}

pub fn triangle_s(triangle: geometry::Triangle,
                  color: orbclient::Color, window: &mut orbclient::window::Window) {
    triangle_p(triangle.p1.x, triangle.p1.y, triangle.p1.z,
               triangle.p2.x, triangle.p2.y, triangle.p2.z,
               triangle.p3.x, triangle.p3.y, triangle.p3.z,
               color, window);
}<commit_msg>Fix lack of reference<commit_after>use orbclient;
use super::super::geometry;
use std;

/// Draw a triangle, from 9 floats representing vertice coordinates
#[allow(dead_code)]
pub fn triangle_p(x1: f32, y1: f32, z1: f32,
                  x2: f32, y2: f32, z2: f32,
                  x3: f32, y3: f32, z3: f32,
                  color: orbclient::Color, window: &mut orbclient::window::Window) {
    use super::{perpective, screen};
    use std::cmp::{min, max};

    // Calculate perspective for points.
    let (x1, y1) = perpective(x1, y1, z1);
    let (x2, y2) = perpective(x2, y2, z2);
    let (x3, y3) = perpective(x3, y3, z3);

    let scr_width  =  window.width() as i32;
    let scr_height = window.height() as i32;

    // Change f32 points into drawable i32, based on screen width,
    let (x1, y1) = screen(x1, y1, scr_width, scr_height);
    let (x2, y2) = screen(x2, y2, scr_width, scr_height);
    let (x3, y3) = screen(x3, y3, scr_width, scr_height);

    let x_low = min(x1, min(x2, x3));
    let x_max = max(x1, max(x2, x3));
    let y_low = min(y1, min(y2, y3));
    let y_max = max(y1, max(y2, y3));

    {
        let x1 = x1 as f32;
        let y1 = y1 as f32;
        let x2 = x2 as f32;
        let y2 = y2 as f32;
        let x3 = x3 as f32;
        let y3 = y3 as f32;

        for x in x_low..x_max {
            for y in y_low..y_max {
                    let mut alpha: f32;
                    let mut beta: f32;
                    let mut gamma: f32;

                    let x = x as f32;
                    let y = y as f32;

                    alpha = ((y2 - y3)*(x - x3) + (x3 - x2)*(y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3));
                    beta = ((y3 - y1)*(x - x3) + (x1 - x3)*(y - y3)) / ((y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3));
                    gamma = 1.0 - alpha - beta;

                    if alpha > 0.0 && beta > 0.0 && gamma > 0.0 {
                        window.pixel(x as i32, y as i32, color);
                    }
            }
        }
    }

    window.line(x1, y1, x2, y2, color);
    window.line(x2, y2, x3, y3, color);
    window.line(x3, y3, x1, y1, color);
}

pub fn triangle_s(triangle: &geometry::Triangle,
                  color: orbclient::Color, window: &mut orbclient::window::Window) {
    triangle_p(triangle.p1.x, triangle.p1.y, triangle.p1.z,
               triangle.p2.x, triangle.p2.y, triangle.p2.z,
               triangle.p3.x, triangle.p3.y, triangle.p3.z,
               color, window);
}<|endoftext|>


<commit_before><commit_msg>else conditional added<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #74671 - rust-lang:const-generics-coerce-unsized, r=nikomatsakis<commit_after><|endoftext|>


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

// Functions for dealing with devices.

use std::fs::File;
use std::io::{Seek, Write, SeekFrom};
use std::fs::OpenOptions;
use std::os::unix::prelude::AsRawFd;
use std::path::Path;

use devicemapper::consts::SECTOR_SIZE;
use devicemapper::{Bytes, Sectors};

use super::super::errors::{EngineResult, EngineError};

ioctl!(read blkgetsize64 with 0x12, 114; u64);

pub fn blkdev_size(file: &File) -> EngineResult<Bytes> {
    let mut val: u64 = 0;

    match unsafe { blkgetsize64(file.as_raw_fd(), &mut val) } {
        Err(x) => Err(EngineError::Nix(x)),
        Ok(_) => Ok(Bytes(val)),
    }
}

/// Write buf at offset length times.
pub fn write_sectors(path: &Path,
                     offset: Sectors,
                     length: Sectors,
                     buf: &[u8; SECTOR_SIZE])
                     -> EngineResult<()> {
    let mut f = try!(OpenOptions::new().write(true).open(path));

    try!(f.seek(SeekFrom::Start(*offset)));
    for _ in 0..*length {
        try!(f.write_all(buf));
    }

    try!(f.flush());
    Ok(())
}

/// Zero sectors at the given offset for length sectors.
pub fn wipe_sectors(path: &Path, offset: Sectors, length: Sectors) -> EngineResult<()> {
    write_sectors(path, offset, length, &[0u8; SECTOR_SIZE])
}
<commit_msg>Broaden argument type for wipe_sectors and write_sectors<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Functions for dealing with devices.

use std::fs::File;
use std::io::{Seek, Write, SeekFrom};
use std::fs::OpenOptions;
use std::os::unix::prelude::AsRawFd;
use std::path::Path;

use devicemapper::consts::SECTOR_SIZE;
use devicemapper::{Bytes, Sectors};

use super::super::errors::{EngineResult, EngineError};

ioctl!(read blkgetsize64 with 0x12, 114; u64);

pub fn blkdev_size(file: &File) -> EngineResult<Bytes> {
    let mut val: u64 = 0;

    match unsafe { blkgetsize64(file.as_raw_fd(), &mut val) } {
        Err(x) => Err(EngineError::Nix(x)),
        Ok(_) => Ok(Bytes(val)),
    }
}

/// Write buf at offset length times.
pub fn write_sectors<P: AsRef<Path>>(path: P,
                                     offset: Sectors,
                                     length: Sectors,
                                     buf: &[u8; SECTOR_SIZE])
                                     -> EngineResult<()> {
    let mut f = try!(OpenOptions::new().write(true).open(path));

    try!(f.seek(SeekFrom::Start(*offset)));
    for _ in 0..*length {
        try!(f.write_all(buf));
    }

    try!(f.flush());
    Ok(())
}

/// Zero sectors at the given offset for length sectors.
pub fn wipe_sectors<P: AsRef<Path>>(path: P, offset: Sectors, length: Sectors) -> EngineResult<()> {
    write_sectors(path, offset, length, &[0u8; SECTOR_SIZE])
}
<|endoftext|>


<commit_before><commit_msg>command refactor<commit_after><|endoftext|>


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