<commit_before><commit_msg>Main rename<commit_after>#![cfg_attr(test, allow(dead_code))]

mod byte_conversion;
mod byte_manipulation;
mod byte_utilities;
mod english_scoring;
mod general_utilities;
mod key;

fn guess_single_xor_char_decode(bytes: &Vec<u8>) -> (u16, Vec<u8>, u8) {
	let mut top_score = 0;
	let mut top_decode = vec![];
	let mut top_x = 0;
	for x in 0..255 {
		let mut spin: Vec<u8> = vec![];
		while spin.len() < bytes.len() {
			spin.push(x);
		}

		let decoded = byte_manipulation::xor_byte_streams(&bytes, &spin);
		let score = english_scoring::score_on_letter_frequency(&decoded);
		if score > top_score {
			top_score = score;
			top_decode = decoded;
			top_x = x;
		}
	}

	(top_score, top_decode, top_x)
}

fn problem_3() {
	// http://cryptopals.com/sets/1/challenges/3/
	use byte_conversion::*;
	let encoded = hex_to_bytes("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736");

	let (top_score, top_decode, _) = guess_single_xor_char_decode(&encoded);

	println!("Best guess: `{}`, with a score of {}.", bytes_to_readable_text(&top_decode), top_score);
}

fn problem_4() {
	// http://cryptopals.com/sets/1/challenges/4/

	use byte_conversion::*;

	let s = general_utilities::read_file("C:\\Users\\Topher\\Dropbox\\Public\\Programming\\Matasano\\matasano-crypto-challenges\\res\\4.txt");

	let mut top_score = 0;
	let mut top_decode = vec![];
    for line in s.split("\n") {
    	let (score, decoded, x) = guess_single_xor_char_decode(&hex_to_bytes(line));

		if score > top_score {
			top_score = score;
			top_decode = decoded.clone();
		}

    }

    println!("\n\n\n{} -      `{}`", top_score, bytes_to_readable_text(&top_decode));
}

fn problem_6() {
	// http://cryptopals.com/sets/1/challenges/6/

	use byte_conversion::*;
	use byte_manipulation::*;
	use byte_utilities::*;
	use english_scoring::*;
	use general_utilities::*;
	use key::*;

	let file_data = general_utilities::read_file("C:\\Users\\Topher\\Dropbox\\Public\\Programming\\Matasano\\matasano-crypto-challenges\\res\\6.txt");
	let data_bytes = readable_text_to_bytes(&file_data);

	// For each KEYSIZE, take the first KEYSIZE worth of bytes, and the second KEYSIZE worth of bytes,
	// and find the edit distance between them. Normalize this result by dividing by KEYSIZE.
	// The KEYSIZE with the smallest normalized edit distance is probably the key.
	//  You could proceed perhaps with the smallest 2-3 KEYSIZE values. Or take 4 KEYSIZE blocks instead of 2 and average the distances.
	let mut keysize_points = Vec::new();
	for keysize in 2..41 {
		if data_bytes.len() < keysize * 4 {
			continue;
		}

		let chunks: Vec<_> = data_bytes.chunks(keysize).map(|x| slice_to_vec(x)).collect();
		assert!(chunks.len() >= 4);

		let distance1 = hamming_distance(&chunks[0], &chunks[1]);
		let distance2 = hamming_distance(&chunks[1], &chunks[2]);
		let distance3 = hamming_distance(&chunks[2], &chunks[3]);
		let distance4 = hamming_distance(&chunks[0], &chunks[3]);
		let avg_distance: f32 = (distance1 + distance2 + distance3 + distance4) as f32 / 4.0;
		let normalized_distance = avg_distance / keysize as f32;

		let pair = (keysize, normalized_distance);
		keysize_points.push(pair);
	}

	// Find the 4 best keysize values
	keysize_points.sort_by(|a, b| {
		use std::cmp::Ordering::*;

		let (_, x) = *a;
		let (_, y) = *b;

		x.partial_cmp(&y).unwrap_or(Equal)
	});

	println!("{:?}", keysize_points);

	let (best_keysize, _) = keysize_points[0];
	println!("{:?}", best_keysize);

	// Now that you probably know the KEYSIZE: break the ciphertext into blocks of KEYSIZE length.
	let blocks: Vec<Vec<u8>> = data_bytes
		.chunks(best_keysize)
		.map(|x| slice_to_vec(x))
		.collect();

	// Now transpose the blocks: make a block that is the first byte of every block, and a block that is the second byte of every block, and so on.
	let transposed_blocks: Vec<Vec<u8>> = transpose_chunks(&blocks);

	// Solve each block as if it was single-character XOR. You already have code to do this.
	let solved_key: Vec<(u16, String, u8)> = transposed_blocks.iter()
		.map(|x| {
			let (a, b, c) = guess_single_xor_char_decode(x);
			(a, bytes_to_readable_text(&b), c)
		})
		.collect();

	// For each block, the single-byte XOR key that produces the best looking histogram is the repeating-key XOR key byte for that block.
	// Put them together and you have the key.
	//let final_blocks: Vec<Vec<u8>> = transpose_chunks(&solved_blocks);

	//let r: Vec<String> = final_blocks.iter().map(|x| bytes_to_readable_text(x)).collect();
	//println!("{:?}", transposed_blocks.iter().map(|x| bytes_to_readable_text(x)).collect());
	println!("{:?}", solved_key);

	let mut rk = RepeatingKey::new(&"\u{0}\u{3}\u{0}\u{3}\u{0}\u{0}\u{3}\u{3}\u{3}\u{0}\u{3}\u{0}\u{3}\u{0}\u{2}\u{3}\u{3}\u{2}\u{3}\u{0}");

	//println!("{:?}", bytes_to_readable_text(&rk.encrypt_bytes(&transposed_blocks)));
}

fn main() {
	println!("Running.");

	problem_6();
}<|endoftext|>


<commit_before>use libimagstore::store::Entry;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use viewer::Viewer;
use result::Result;
use error::ViewErrorKind as VEK;

pub struct VersionsViewer<'a> {
    store: &'a Store,
}

impl<'a> VersionsViewer<'a> {

    pub fn new(store: &'a Store) -> VersionsViewer<'a> {
        VersionsViewer {
            store: store,
        }
    }

}

impl<'a> Viewer for VersionsViewer<'a> {

    fn view_entry(&self, entr: &Entry) -> Result<()> {
        use glob::glob;

        entr.get_location()
            .clone()
            .storified(self.store)
            .to_str()
            .and_then(|s| s.split("~").next())
            .map(|component| {
                glob(&format!("{}~*", component)[..])
                    .map_err(|_| VEK::PatternError.into_error())
                    .and_then(|paths| {
                        for entry in paths {
                            let p = match entry {
                                Err(_) => return Err(VEK::GlobError.into_error()),
                                Ok(p) => p,
                            };
                            let p = p.file_name()
                                .and_then(|s| s.to_str())
                                .unwrap(); // TODO
                            println!("{}", p);
                        };
                        Ok(())
                    })
            })
            .unwrap_or(Err(VEK::PatternBuildingError.into_error()))
    }

}

<commit_msg>Fix libimagentryview::builtin::versions::* for new StoreId interface<commit_after>use libimagstore::store::Entry;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use viewer::Viewer;
use result::Result;
use error::ViewErrorKind as VEK;
use error::MapErrInto;

pub struct VersionsViewer<'a> {
    store: &'a Store,
}

impl<'a> VersionsViewer<'a> {

    pub fn new(store: &'a Store) -> VersionsViewer<'a> {
        VersionsViewer {
            store: store,
        }
    }

}

impl<'a> Viewer for VersionsViewer<'a> {

    fn view_entry(&self, entr: &Entry) -> Result<()> {
        use glob::glob;

        entr.get_location()
            .clone()
            .with_base(self.store.path().clone())
            .to_str()
            .map_err_into(VEK::ViewError)
            .and_then(|s| {
                s.split("~")
                    .next()
                    .ok_or(VEK::PatternError.into_error())
                    .map(|s| format!("{}~*", s))
                    .and_then(|pat| glob(&pat[..]).map_err(|_| VEK::PatternError.into_error()))
                    .and_then(|paths| {
                        for entry in paths {
                            println!("{}",
                                try!(entry
                                     .map_err(|_| VEK::GlobError.into_error()))
                                     .file_name()
                                     .and_then(|s| s.to_str())
                                     .unwrap() // TODO
                                );
                        };
                        Ok(())
                    })
            })
    }

}

<|endoftext|>


<commit_before>use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<commit_msg>Impl From<GitHookError> for HookError<commit_after>use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

impl From<GitHookError> for HE {

    fn from(he: GitHookError) -> HE {
        HE::new(HEK::HookExecutionError, Some(Box::new(he)))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<|endoftext|>


<commit_before><commit_msg>Remove some boxing<commit_after><|endoftext|>


<commit_before><commit_msg>Add some XML character predicates<commit_after>use super::{Document,Root,RootChild};

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Print all errors<commit_after><|endoftext|>


<commit_before><commit_msg>Add test.<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.

// aux-build:two_macros.rs

macro_rules! foo { () => {} }
macro_rules! macro_one { () => {} }

macro_rules! m1 { () => {
    macro_rules! foo { () => {} } //~ ERROR `foo` is already in scope
    //~^ NOTE macro-expanded `macro_rules!`s and `#[macro_use]`s may not shadow existing macros

    #[macro_use] //~ ERROR `macro_one` is already in scope
    //~^ NOTE macro-expanded `macro_rules!`s and `#[macro_use]`s may not shadow existing macros
    extern crate two_macros;
}}
m1!(); //~ NOTE in this expansion
       //~| NOTE in this expansion
       //~| NOTE in this expansion
       //~| NOTE in this expansion

fn f() { macro_one!(); }
foo!();

macro_rules! m2 { () => {
    macro_rules! foo { () => {} }
    #[macro_use] extern crate two_macros as __;

    fn g() { macro_one!(); }
    foo!();
}}
m2!();
//^ Since `foo` and `macro_one` are not used outside this expansion, they are not shadowing errors.

fn main() {}
<|endoftext|>


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

#![feature(int_uint)]
#![feature(unboxed_closures)]
#![feature(box_syntax)]

#![deny(unused_imports)]
#![deny(unused_variables)]
#![allow(missing_copy_implementations)]
#![allow(unstable)]

extern crate collections;
extern crate geom;
extern crate hyper;
extern crate png;
#[macro_use]
extern crate log;
extern crate serialize;
extern crate "util" as servo_util;
extern crate stb_image;
extern crate time;
extern crate url;

/// Image handling.
///
/// It may be surprising that this goes in the network crate as opposed to the graphics crate.
/// However, image handling is generally very integrated with the network stack (especially where
/// caching is involved) and as a result it must live in here.
pub mod image {
    pub mod base;
    pub mod holder;
}

pub mod about_loader;
pub mod file_loader;
pub mod http_loader;
pub mod data_loader;
pub mod image_cache_task;
pub mod local_image_cache;
pub mod resource_task;
pub mod storage_task;
mod sniffer_task;

/// An implementation of the [Fetch spec](http://fetch.spec.whatwg.org/)
pub mod fetch {
    #![allow(dead_code)] // XXXManishearth this is only temporary until the Fetch mod starts being used
    pub mod request;
    pub mod response;
    pub mod cors_cache;
}
<commit_msg>silence fetch warnings<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(int_uint)]
#![feature(unboxed_closures)]
#![feature(box_syntax)]

#![deny(unused_imports)]
#![deny(unused_variables)]
#![allow(missing_copy_implementations)]
#![allow(unstable)]

extern crate collections;
extern crate geom;
extern crate hyper;
extern crate png;
#[macro_use]
extern crate log;
extern crate serialize;
extern crate "util" as servo_util;
extern crate stb_image;
extern crate time;
extern crate url;

/// Image handling.
///
/// It may be surprising that this goes in the network crate as opposed to the graphics crate.
/// However, image handling is generally very integrated with the network stack (especially where
/// caching is involved) and as a result it must live in here.
pub mod image {
    pub mod base;
    pub mod holder;
}

pub mod about_loader;
pub mod file_loader;
pub mod http_loader;
pub mod data_loader;
pub mod image_cache_task;
pub mod local_image_cache;
pub mod resource_task;
pub mod storage_task;
mod sniffer_task;

/// An implementation of the [Fetch spec](http://fetch.spec.whatwg.org/)
pub mod fetch {
    #![allow(dead_code, unused)] // XXXManishearth this is only temporary until the Fetch mod starts being used
    pub mod request;
    pub mod response;
    pub mod cors_cache;
}
<|endoftext|>


<commit_before>// Copyright 2012-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.
//! Set and unset common attributes on LLVM values.

use libc::{c_uint, c_ulonglong};
use llvm::{self, ValueRef, AttrHelper};
use middle::ty::{self, ClosureTyper};
use session::config::NoDebugInfo;
use syntax::abi;
use syntax::ast;
pub use syntax::attr::InlineAttr;
use trans::base;
use trans::common;
use trans::context::CrateContext;
use trans::machine;
use trans::type_of;

/// Mark LLVM function to use split stack.
#[inline]
pub fn split_stack(val: ValueRef, set: bool) {
    unsafe {
        let attr = "split-stack\0".as_ptr() as *const _;
        if set {
            llvm::LLVMAddFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
        } else {
            llvm::LLVMRemoveFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
        }
    }
}

/// Mark LLVM function to use provided inline heuristic.
#[inline]
pub fn inline(val: ValueRef, inline: InlineAttr) {
    use self::InlineAttr::*;
    match inline {
        Hint   => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHint),
        Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInline),
        Never  => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInline),
        None   => {
            let attr = llvm::Attribute::InlineHint |
                       llvm::Attribute::AlwaysInline |
                       llvm::Attribute::NoInline;
            unsafe {
                llvm::LLVMRemoveFunctionAttr(val, attr.bits() as c_ulonglong)
            }
        },
    };
}

/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn emit_uwtable(val: ValueRef, emit: bool) {
    if emit {
        llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable);
    } else {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::UWTable.bits() as c_ulonglong,
            );
        }
    }
}

/// Tell LLVM whether the function can or cannot unwind.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn unwind(val: ValueRef, can_unwind: bool) {
    if can_unwind {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::NoUnwind.bits() as c_ulonglong,
            );
        }
    } else {
        llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind);
    }
}

/// Tell LLVM whether it should optimise function for size.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
    if optimize {
        llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize);
    } else {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::OptimizeForSize.bits() as c_ulonglong,
            );
        }
    }
}

/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
    use syntax::attr::*;
    inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));

    // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
    // parameter.
    let no_fp_elim = (ccx.sess().opts.debuginfo != NoDebugInfo) ||
                     !ccx.sess().target.target.options.eliminate_frame_pointer;
    if no_fp_elim {
        unsafe {
            let attr = "no-frame-pointer-elim\0".as_ptr() as *const _;
            let val = "true\0".as_ptr() as *const _;
            llvm::LLVMAddFunctionAttrStringValue(llfn,
                                                 llvm::FunctionIndex as c_uint,
                                                 attr, val);
        }
    }

    for attr in attrs {
        if attr.check_name("no_stack_check") {
            split_stack(llfn, false);
        } else if attr.check_name("cold") {
            unsafe {
                llvm::LLVMAddFunctionAttribute(llfn,
                                               llvm::FunctionIndex as c_uint,
                                               llvm::ColdAttribute as u64)
            }
        } else if attr.check_name("allocator") {
            llvm::Attribute::NoAlias.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
        }
    }
}

/// Composite function which converts function type into LLVM attributes for the function.
pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx>)
                              -> llvm::AttrBuilder {
    use middle::ty::{BrAnon, ReLateBound};

    let function_type;
    let (fn_sig, abi, env_ty) = match fn_type.sty {
        ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
        ty::TyClosure(closure_did, substs) => {
            let typer = common::NormalizingClosureTyper::new(ccx.tcx());
            function_type = typer.closure_type(closure_did, substs);
            let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
            (&function_type.sig, abi::RustCall, Some(self_type))
        }
        _ => ccx.sess().bug("expected closure or function.")
    };

    let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);

    let mut attrs = llvm::AttrBuilder::new();
    let ret_ty = fn_sig.output;

    // These have an odd calling convention, so we need to manually
    // unpack the input ty's
    let input_tys = match fn_type.sty {
        ty::TyClosure(..) => {
            assert!(abi == abi::RustCall);

            match fn_sig.inputs[0].sty {
                ty::TyTuple(ref inputs) => {
                    let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
                    full_inputs.push_all(inputs);
                    full_inputs
                }
                _ => ccx.sess().bug("expected tuple'd inputs")
            }
        },
        ty::TyBareFn(..) if abi == abi::RustCall => {
            let mut inputs = vec![fn_sig.inputs[0]];

            match fn_sig.inputs[1].sty {
                ty::TyTuple(ref t_in) => {
                    inputs.push_all(&t_in[..]);
                    inputs
                }
                _ => ccx.sess().bug("expected tuple'd inputs")
            }
        }
        _ => fn_sig.inputs.clone()
    };

    // Index 0 is the return value of the llvm func, so we start at 1
    let mut first_arg_offset = 1;
    if let ty::FnConverging(ret_ty) = ret_ty {
        // A function pointer is called without the declaration
        // available, so we have to apply any attributes with ABI
        // implications directly to the call instruction. Right now,
        // the only attribute we need to worry about is `sret`.
        if type_of::return_uses_outptr(ccx, ret_ty) {
            let llret_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, ret_ty));

            // The outptr can be noalias and nocapture because it's entirely
            // invisible to the program. We also know it's nonnull as well
            // as how many bytes we can dereference
            attrs.arg(1, llvm::Attribute::StructRet)
                 .arg(1, llvm::Attribute::NoAlias)
                 .arg(1, llvm::Attribute::NoCapture)
                 .arg(1, llvm::DereferenceableAttribute(llret_sz));

            // Add one more since there's an outptr
            first_arg_offset += 1;
        } else {
            // The `noalias` attribute on the return value is useful to a
            // function ptr caller.
            match ret_ty.sty {
                // `Box` pointer return values never alias because ownership
                // is transferred
                ty::TyBox(it) if common::type_is_sized(ccx.tcx(), it) => {
                    attrs.ret(llvm::Attribute::NoAlias);
                }
                _ => {}
            }

            // We can also mark the return value as `dereferenceable` in certain cases
            match ret_ty.sty {
                // These are not really pointers but pairs, (pointer, len)
                ty::TyRef(_, ty::mt { ty: inner, .. })
                | ty::TyBox(inner) if common::type_is_sized(ccx.tcx(), inner) => {
                    let llret_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
                    attrs.ret(llvm::DereferenceableAttribute(llret_sz));
                }
                _ => {}
            }

            if let ty::TyBool = ret_ty.sty {
                attrs.ret(llvm::Attribute::ZExt);
            }
        }
    }

    for (idx, &t) in input_tys.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
        match t.sty {
            // this needs to be first to prevent fat pointers from falling through
            _ if !common::type_is_immediate(ccx, t) => {
                let llarg_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, t));

                // For non-immediate arguments the callee gets its own copy of
                // the value on the stack, so there are no aliases. It's also
                // program-invisible so can't possibly capture
                attrs.arg(idx, llvm::Attribute::NoAlias)
                     .arg(idx, llvm::Attribute::NoCapture)
                     .arg(idx, llvm::DereferenceableAttribute(llarg_sz));
            }

            ty::TyBool => {
                attrs.arg(idx, llvm::Attribute::ZExt);
            }

            // `Box` pointer parameters never alias because ownership is transferred
            ty::TyBox(inner) => {
                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));

                attrs.arg(idx, llvm::Attribute::NoAlias)
                     .arg(idx, llvm::DereferenceableAttribute(llsz));
            }

            // `&mut` pointer parameters never alias other parameters, or mutable global data
            //
            // `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as both
            // `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely on
            // memory dependencies rather than pointer equality
            ty::TyRef(b, mt) if mt.mutbl == ast::MutMutable ||
                                  !ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe() => {

                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
                attrs.arg(idx, llvm::Attribute::NoAlias)
                     .arg(idx, llvm::DereferenceableAttribute(llsz));

                if mt.mutbl == ast::MutImmutable {
                    attrs.arg(idx, llvm::Attribute::ReadOnly);
                }

                if let ReLateBound(_, BrAnon(_)) = *b {
                    attrs.arg(idx, llvm::Attribute::NoCapture);
                }
            }

            // When a reference in an argument has no named lifetime, it's impossible for that
            // reference to escape this function (returned or stored beyond the call by a closure).
            ty::TyRef(&ReLateBound(_, BrAnon(_)), mt) => {
                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
                attrs.arg(idx, llvm::Attribute::NoCapture)
                     .arg(idx, llvm::DereferenceableAttribute(llsz));
            }

            // & pointer parameters are also never null and we know exactly how
            // many bytes we can dereference
            ty::TyRef(_, mt) => {
                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
                attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
            }
            _ => ()
        }
    }

    attrs
}
<commit_msg>Use a single match arm for all TyRef variants when deducing function argument attributes<commit_after>// Copyright 2012-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.
//! Set and unset common attributes on LLVM values.

use libc::{c_uint, c_ulonglong};
use llvm::{self, ValueRef, AttrHelper};
use middle::ty::{self, ClosureTyper};
use session::config::NoDebugInfo;
use syntax::abi;
use syntax::ast;
pub use syntax::attr::InlineAttr;
use trans::base;
use trans::common;
use trans::context::CrateContext;
use trans::machine;
use trans::type_of;

/// Mark LLVM function to use split stack.
#[inline]
pub fn split_stack(val: ValueRef, set: bool) {
    unsafe {
        let attr = "split-stack\0".as_ptr() as *const _;
        if set {
            llvm::LLVMAddFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
        } else {
            llvm::LLVMRemoveFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
        }
    }
}

/// Mark LLVM function to use provided inline heuristic.
#[inline]
pub fn inline(val: ValueRef, inline: InlineAttr) {
    use self::InlineAttr::*;
    match inline {
        Hint   => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHint),
        Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInline),
        Never  => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInline),
        None   => {
            let attr = llvm::Attribute::InlineHint |
                       llvm::Attribute::AlwaysInline |
                       llvm::Attribute::NoInline;
            unsafe {
                llvm::LLVMRemoveFunctionAttr(val, attr.bits() as c_ulonglong)
            }
        },
    };
}

/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn emit_uwtable(val: ValueRef, emit: bool) {
    if emit {
        llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable);
    } else {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::UWTable.bits() as c_ulonglong,
            );
        }
    }
}

/// Tell LLVM whether the function can or cannot unwind.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn unwind(val: ValueRef, can_unwind: bool) {
    if can_unwind {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::NoUnwind.bits() as c_ulonglong,
            );
        }
    } else {
        llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind);
    }
}

/// Tell LLVM whether it should optimise function for size.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
    if optimize {
        llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize);
    } else {
        unsafe {
            llvm::LLVMRemoveFunctionAttr(
                val,
                llvm::Attribute::OptimizeForSize.bits() as c_ulonglong,
            );
        }
    }
}

/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
    use syntax::attr::*;
    inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));

    // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
    // parameter.
    let no_fp_elim = (ccx.sess().opts.debuginfo != NoDebugInfo) ||
                     !ccx.sess().target.target.options.eliminate_frame_pointer;
    if no_fp_elim {
        unsafe {
            let attr = "no-frame-pointer-elim\0".as_ptr() as *const _;
            let val = "true\0".as_ptr() as *const _;
            llvm::LLVMAddFunctionAttrStringValue(llfn,
                                                 llvm::FunctionIndex as c_uint,
                                                 attr, val);
        }
    }

    for attr in attrs {
        if attr.check_name("no_stack_check") {
            split_stack(llfn, false);
        } else if attr.check_name("cold") {
            unsafe {
                llvm::LLVMAddFunctionAttribute(llfn,
                                               llvm::FunctionIndex as c_uint,
                                               llvm::ColdAttribute as u64)
            }
        } else if attr.check_name("allocator") {
            llvm::Attribute::NoAlias.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
        }
    }
}

/// Composite function which converts function type into LLVM attributes for the function.
pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx>)
                              -> llvm::AttrBuilder {
    use middle::ty::{BrAnon, ReLateBound};

    let function_type;
    let (fn_sig, abi, env_ty) = match fn_type.sty {
        ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
        ty::TyClosure(closure_did, substs) => {
            let typer = common::NormalizingClosureTyper::new(ccx.tcx());
            function_type = typer.closure_type(closure_did, substs);
            let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
            (&function_type.sig, abi::RustCall, Some(self_type))
        }
        _ => ccx.sess().bug("expected closure or function.")
    };

    let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);

    let mut attrs = llvm::AttrBuilder::new();
    let ret_ty = fn_sig.output;

    // These have an odd calling convention, so we need to manually
    // unpack the input ty's
    let input_tys = match fn_type.sty {
        ty::TyClosure(..) => {
            assert!(abi == abi::RustCall);

            match fn_sig.inputs[0].sty {
                ty::TyTuple(ref inputs) => {
                    let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
                    full_inputs.push_all(inputs);
                    full_inputs
                }
                _ => ccx.sess().bug("expected tuple'd inputs")
            }
        },
        ty::TyBareFn(..) if abi == abi::RustCall => {
            let mut inputs = vec![fn_sig.inputs[0]];

            match fn_sig.inputs[1].sty {
                ty::TyTuple(ref t_in) => {
                    inputs.push_all(&t_in[..]);
                    inputs
                }
                _ => ccx.sess().bug("expected tuple'd inputs")
            }
        }
        _ => fn_sig.inputs.clone()
    };

    // Index 0 is the return value of the llvm func, so we start at 1
    let mut first_arg_offset = 1;
    if let ty::FnConverging(ret_ty) = ret_ty {
        // A function pointer is called without the declaration
        // available, so we have to apply any attributes with ABI
        // implications directly to the call instruction. Right now,
        // the only attribute we need to worry about is `sret`.
        if type_of::return_uses_outptr(ccx, ret_ty) {
            let llret_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, ret_ty));

            // The outptr can be noalias and nocapture because it's entirely
            // invisible to the program. We also know it's nonnull as well
            // as how many bytes we can dereference
            attrs.arg(1, llvm::Attribute::StructRet)
                 .arg(1, llvm::Attribute::NoAlias)
                 .arg(1, llvm::Attribute::NoCapture)
                 .arg(1, llvm::DereferenceableAttribute(llret_sz));

            // Add one more since there's an outptr
            first_arg_offset += 1;
        } else {
            // The `noalias` attribute on the return value is useful to a
            // function ptr caller.
            match ret_ty.sty {
                // `Box` pointer return values never alias because ownership
                // is transferred
                ty::TyBox(it) if common::type_is_sized(ccx.tcx(), it) => {
                    attrs.ret(llvm::Attribute::NoAlias);
                }
                _ => {}
            }

            // We can also mark the return value as `dereferenceable` in certain cases
            match ret_ty.sty {
                // These are not really pointers but pairs, (pointer, len)
                ty::TyRef(_, ty::mt { ty: inner, .. })
                | ty::TyBox(inner) if common::type_is_sized(ccx.tcx(), inner) => {
                    let llret_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
                    attrs.ret(llvm::DereferenceableAttribute(llret_sz));
                }
                _ => {}
            }

            if let ty::TyBool = ret_ty.sty {
                attrs.ret(llvm::Attribute::ZExt);
            }
        }
    }

    for (idx, &t) in input_tys.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
        match t.sty {
            // this needs to be first to prevent fat pointers from falling through
            _ if !common::type_is_immediate(ccx, t) => {
                let llarg_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, t));

                // For non-immediate arguments the callee gets its own copy of
                // the value on the stack, so there are no aliases. It's also
                // program-invisible so can't possibly capture
                attrs.arg(idx, llvm::Attribute::NoAlias)
                     .arg(idx, llvm::Attribute::NoCapture)
                     .arg(idx, llvm::DereferenceableAttribute(llarg_sz));
            }

            ty::TyBool => {
                attrs.arg(idx, llvm::Attribute::ZExt);
            }

            // `Box` pointer parameters never alias because ownership is transferred
            ty::TyBox(inner) => {
                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));

                attrs.arg(idx, llvm::Attribute::NoAlias)
                     .arg(idx, llvm::DereferenceableAttribute(llsz));
            }

            ty::TyRef(b, mt) => {
                // `&mut` pointer parameters never alias other parameters, or mutable global data
                //
                // `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as
                // both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely
                // on memory dependencies rather than pointer equality
                let interior_unsafe = ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe();

                if mt.mutbl == ast::MutMutable || !interior_unsafe {
                    attrs.arg(idx, llvm::Attribute::NoAlias);
                }

                if mt.mutbl == ast::MutImmutable && !interior_unsafe {
                    attrs.arg(idx, llvm::Attribute::ReadOnly);
                }

                // & pointer parameters are also never null and we know exactly
                // how many bytes we can dereference
                let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
                attrs.arg(idx, llvm::DereferenceableAttribute(llsz));

                // When a reference in an argument has no named lifetime, it's
                // impossible for that reference to escape this function
                // (returned or stored beyond the call by a closure).
                if let ReLateBound(_, BrAnon(_)) = *b {
                    attrs.arg(idx, llvm::Attribute::NoCapture);
                }
            }

            _ => ()
        }
    }

    attrs
}
<|endoftext|>


<commit_before><commit_msg>fix clip warning about short idents<commit_after><|endoftext|>


<commit_before><commit_msg>decrease bench reps<commit_after><|endoftext|>


<commit_before><commit_msg>some functional tests for mpsc<commit_after>extern crate mioco;

use mioco::sync::mpsc;
use std::thread;

#[test]
fn tx_rx_outside_mioco() {
    let (tx, rx) = mpsc::channel::<i32>();

    thread::spawn(move || for i in 0..10 {
                      let _ = tx.send(i);
                  });

    thread::sleep_ms(1000);

    let mut sum = 0;
    for _ in 0..50 {
        if let Ok(i) = rx.try_recv() {
            sum += i;
        }
    }

    assert_eq!(sum, 45);
}

#[test]
fn tx_outside_rx_inside_mioco() {
    let (tx, rx) = mpsc::channel::<i32>();
    for i in 0..10 {
        let _ = tx.send(i);
    }

    mioco::spawn(move || {
        let mut sum = 0;
        for _ in 0..50 {
            if let Ok(i) = rx.try_recv() {
                sum += i;
            }
        }
        assert_eq!(sum, 45);
    });

    thread::sleep_ms(1000);
}

#[test]
fn tx_inside_rx_inside_mioco() {
    let (tx, rx) = mpsc::channel::<i32>();

    mioco::spawn(move ||{
        for i in 0..10 {
            let _ = tx.send(i);
        }
    });

    mioco::spawn(move || {
        let mut sum = 0;
        for _ in 0..50 {
            if let Ok(i) = rx.try_recv() {
                sum += i;
            }
        }
        assert_eq!(sum, 45);
    });

    thread::sleep_ms(1000);
}
<|endoftext|>


<commit_before><commit_msg>Stop using deprecated `SipHasher`.<commit_after><|endoftext|>


<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.

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(asm)]
#![feature(staged_api)]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

extern {
    fn memmove(dst: *mut u8, src: *const u8, size: usize);
    fn __rust_allocate(size: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize;
    fn __rust_usable_size(size: usize, align: usize) -> usize;
 }
<commit_msg>run rustfmt on liballoc_system<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.

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(asm)]
#![feature(staged_api)]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

extern "C" {
    fn memmove(dst: *mut u8, src: *const u8, size: usize);
    fn __rust_allocate(size: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8,
                                 old_size: usize,
                                 size: usize,
                                 align: usize)
                                 -> usize;
    fn __rust_usable_size(size: usize, align: usize) -> usize;
}
<|endoftext|>


<commit_before><commit_msg>Write tailed data to stdout, and cleanup a tad.<commit_after><|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>Style adjustments<commit_after><|endoftext|>


<commit_before><commit_msg>Fix config override mechanism<commit_after><|endoftext|>


<commit_before>//! Matrix room version identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};

use crate::error::Error;

/// Room version identifiers cannot be more than 32 code points.
const MAX_CODE_POINTS: usize = 32;

/// A Matrix room version ID.
///
/// A `RoomVersionId` can be or converted or deserialized from a string slice, and can be converted
/// or serialized back into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::RoomVersionId;
/// assert_eq!(RoomVersionId::try_from("1").unwrap().to_string(), "1");
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct RoomVersionId(InnerRoomVersionId);

/// Possibile values for room version, distinguishing between official Matrix versions and custom
/// versions.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum InnerRoomVersionId {
    /// A version 1 room.
    Version1,
    /// A version 2 room.
    Version2,
    /// A version 3 room.
    Version3,
    /// A version 4 room.
    Version4,
    /// A custom room version.
    Custom(String),
}

/// A serde visitor for `RoomVersionId`.
struct RoomVersionIdVisitor;

impl RoomVersionId {
    /// Creates a version 1 room ID.
    pub fn version_1() -> Self {
        Self(InnerRoomVersionId::Version1)
    }

    /// Creates a version 2 room ID.
    pub fn version_2() -> Self {
        Self(InnerRoomVersionId::Version2)
    }

    /// Creates a version 3 room ID.
    pub fn version_3() -> Self {
        Self(InnerRoomVersionId::Version3)
    }

    /// Creates a version 4 room ID.
    pub fn version_4() -> Self {
        Self(InnerRoomVersionId::Version4)
    }

    /// Creates a custom room version ID from the given string slice.
    pub fn custom(id: &str) -> Self {
        Self(InnerRoomVersionId::Custom(id.to_string()))
    }

    /// Whether or not this room version is an official one specified by the Matrix protocol.
    pub fn is_official(&self) -> bool {
        !self.is_custom()
    }

    /// Whether or not this is a custom room version.
    pub fn is_custom(&self) -> bool {
        match self.0 {
            InnerRoomVersionId::Custom(_) => true,
            _ => false,
        }
    }

    /// Whether or not this is a version 1 room.
    pub fn is_version_1(&self) -> bool {
        self.0 == InnerRoomVersionId::Version1
    }

    /// Whether or not this is a version 2 room.
    pub fn is_version_2(&self) -> bool {
        self.0 == InnerRoomVersionId::Version2
    }

    /// Whether or not this is a version 3 room.
    pub fn is_version_3(&self) -> bool {
        self.0 == InnerRoomVersionId::Version3
    }

    /// Whether or not this is a version 4 room.
    pub fn is_version_4(&self) -> bool {
        self.0 == InnerRoomVersionId::Version4
    }
}

impl Display for RoomVersionId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        let message = match self.0 {
            InnerRoomVersionId::Version1 => "1",
            InnerRoomVersionId::Version2 => "2",
            InnerRoomVersionId::Version3 => "3",
            InnerRoomVersionId::Version4 => "4",
            InnerRoomVersionId::Custom(ref version) => version,
        };

        write!(f, "{}", message)
    }
}

impl Serialize for RoomVersionId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for RoomVersionId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(RoomVersionIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for RoomVersionId {
    type Error = Error;

    /// Attempts to create a new Matrix room version ID from a string representation.
    fn try_from(room_version_id: &'a str) -> Result<Self, Error> {
        let version = match room_version_id {
            "1" => Self(InnerRoomVersionId::Version1),
            "2" => Self(InnerRoomVersionId::Version2),
            "3" => Self(InnerRoomVersionId::Version3),
            "4" => Self(InnerRoomVersionId::Version4),
            custom => {
                if custom.is_empty() {
                    return Err(Error::MinimumLengthNotSatisfied);
                } else if custom.chars().count() > MAX_CODE_POINTS {
                    return Err(Error::MaximumLengthExceeded);
                } else {
                    Self(InnerRoomVersionId::Custom(custom.to_string()))
                }
            }
        };

        Ok(version)
    }
}

impl<'de> Visitor<'de> for RoomVersionIdVisitor {
    type Value = RoomVersionId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix room version ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match RoomVersionId::try_from(v) {
            Ok(room_id) => Ok(room_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::RoomVersionId;
    use crate::error::Error;

    #[test]
    fn valid_version_1_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("1")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "1"
        );
    }
    #[test]
    fn valid_version_2_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("2")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "2"
        );
    }
    #[test]
    fn valid_version_3_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("3")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "3"
        );
    }
    #[test]
    fn valid_version_4_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("4")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "4"
        );
    }

    #[test]
    fn valid_custom_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("io.ruma.1")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "io.ruma.1"
        );
    }

    #[test]
    fn empty_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from(""),
            Err(Error::MinimumLengthNotSatisfied)
        );
    }

    #[test]
    fn over_max_code_point_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("0123456789012345678901234567890123456789"),
            Err(Error::MaximumLengthExceeded)
        );
    }

    #[test]
    fn serialize_official_room_id() {
        assert_eq!(
            to_string(&RoomVersionId::try_from("1").expect("Failed to create RoomVersionId."))
                .expect("Failed to convert RoomVersionId to JSON."),
            r#""1""#
        );
    }

    #[test]
    fn deserialize_official_room_id() {
        let deserialized =
            from_str::<RoomVersionId>(r#""1""#).expect("Failed to convert RoomVersionId to JSON.");

        assert!(deserialized.is_version_1());
        assert!(deserialized.is_official());

        assert_eq!(
            deserialized,
            RoomVersionId::try_from("1").expect("Failed to create RoomVersionId.")
        );
    }

    #[test]
    fn serialize_custom_room_id() {
        assert_eq!(
            to_string(
                &RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.")
            )
            .expect("Failed to convert RoomVersionId to JSON."),
            r#""io.ruma.1""#
        );
    }

    #[test]
    fn deserialize_custom_room_id() {
        let deserialized = from_str::<RoomVersionId>(r#""io.ruma.1""#)
            .expect("Failed to convert RoomVersionId to JSON.");

        assert!(deserialized.is_custom());

        assert_eq!(
            deserialized,
            RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.")
        );
    }

    #[test]
    fn constructors() {
        assert!(RoomVersionId::version_1().is_version_1());
        assert!(RoomVersionId::version_2().is_version_2());
        assert!(RoomVersionId::version_3().is_version_3());
        assert!(RoomVersionId::version_4().is_version_4());
        assert!(RoomVersionId::custom("foo").is_custom());
    }

    #[test]
    fn predicate_methods() {
        let version_1 = RoomVersionId::try_from("1").expect("Failed to create RoomVersionId.");
        let version_2 = RoomVersionId::try_from("2").expect("Failed to create RoomVersionId.");
        let version_3 = RoomVersionId::try_from("3").expect("Failed to create RoomVersionId.");
        let version_4 = RoomVersionId::try_from("4").expect("Failed to create RoomVersionId.");
        let custom = RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.");

        assert!(version_1.is_version_1());
        assert!(version_2.is_version_2());
        assert!(version_3.is_version_3());
        assert!(version_4.is_version_4());

        assert!(!version_1.is_version_2());
        assert!(!version_1.is_version_3());
        assert!(!version_1.is_version_4());

        assert!(version_1.is_official());
        assert!(version_2.is_official());
        assert!(version_3.is_official());
        assert!(version_4.is_official());

        assert!(!version_1.is_custom());
        assert!(!version_2.is_custom());
        assert!(!version_3.is_custom());
        assert!(!version_4.is_custom());

        assert!(custom.is_custom());
        assert!(!custom.is_official());
        assert!(!custom.is_version_1());
        assert!(!custom.is_version_2());
        assert!(!custom.is_version_3());
        assert!(!custom.is_version_4());
    }
}
<commit_msg>Add support for room version 5.<commit_after>//! Matrix room version identifiers.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

#[cfg(feature = "diesel")]
use diesel::sql_types::Text;
use serde::{
    de::{Error as SerdeError, Unexpected, Visitor},
    Deserialize, Deserializer, Serialize, Serializer,
};

use crate::error::Error;

/// Room version identifiers cannot be more than 32 code points.
const MAX_CODE_POINTS: usize = 32;

/// A Matrix room version ID.
///
/// A `RoomVersionId` can be or converted or deserialized from a string slice, and can be converted
/// or serialized back into a string as needed.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::RoomVersionId;
/// assert_eq!(RoomVersionId::try_from("1").unwrap().to_string(), "1");
/// ```
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "diesel", derive(FromSqlRow, QueryId, AsExpression, SqlType))]
#[cfg_attr(feature = "diesel", sql_type = "Text")]
pub struct RoomVersionId(InnerRoomVersionId);

/// Possibile values for room version, distinguishing between official Matrix versions and custom
/// versions.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum InnerRoomVersionId {
    /// A version 1 room.
    Version1,

    /// A version 2 room.
    Version2,

    /// A version 3 room.
    Version3,

    /// A version 4 room.
    Version4,

    /// A version 5 room.
    Version5,

    /// A custom room version.
    Custom(String),
}

/// A serde visitor for `RoomVersionId`.
struct RoomVersionIdVisitor;

impl RoomVersionId {
    /// Creates a version 1 room ID.
    pub fn version_1() -> Self {
        Self(InnerRoomVersionId::Version1)
    }

    /// Creates a version 2 room ID.
    pub fn version_2() -> Self {
        Self(InnerRoomVersionId::Version2)
    }

    /// Creates a version 3 room ID.
    pub fn version_3() -> Self {
        Self(InnerRoomVersionId::Version3)
    }

    /// Creates a version 4 room ID.
    pub fn version_4() -> Self {
        Self(InnerRoomVersionId::Version4)
    }

    /// Creates a version 5 room ID.
    pub fn version_5() -> Self {
        Self(InnerRoomVersionId::Version5)
    }

    /// Creates a custom room version ID from the given string slice.
    pub fn custom(id: &str) -> Self {
        Self(InnerRoomVersionId::Custom(id.to_string()))
    }

    /// Whether or not this room version is an official one specified by the Matrix protocol.
    pub fn is_official(&self) -> bool {
        !self.is_custom()
    }

    /// Whether or not this is a custom room version.
    pub fn is_custom(&self) -> bool {
        match self.0 {
            InnerRoomVersionId::Custom(_) => true,
            _ => false,
        }
    }

    /// Whether or not this is a version 1 room.
    pub fn is_version_1(&self) -> bool {
        self.0 == InnerRoomVersionId::Version1
    }

    /// Whether or not this is a version 2 room.
    pub fn is_version_2(&self) -> bool {
        self.0 == InnerRoomVersionId::Version2
    }

    /// Whether or not this is a version 3 room.
    pub fn is_version_3(&self) -> bool {
        self.0 == InnerRoomVersionId::Version3
    }

    /// Whether or not this is a version 4 room.
    pub fn is_version_4(&self) -> bool {
        self.0 == InnerRoomVersionId::Version4
    }

    /// Whether or not this is a version 5 room.
    pub fn is_version_5(&self) -> bool {
        self.0 == InnerRoomVersionId::Version5
    }
}

impl Display for RoomVersionId {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        let message = match self.0 {
            InnerRoomVersionId::Version1 => "1",
            InnerRoomVersionId::Version2 => "2",
            InnerRoomVersionId::Version3 => "3",
            InnerRoomVersionId::Version4 => "4",
            InnerRoomVersionId::Version5 => "5",
            InnerRoomVersionId::Custom(ref version) => version,
        };

        write!(f, "{}", message)
    }
}

impl Serialize for RoomVersionId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl<'de> Deserialize<'de> for RoomVersionId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_any(RoomVersionIdVisitor)
    }
}

impl<'a> TryFrom<&'a str> for RoomVersionId {
    type Error = Error;

    /// Attempts to create a new Matrix room version ID from a string representation.
    fn try_from(room_version_id: &'a str) -> Result<Self, Error> {
        let version = match room_version_id {
            "1" => Self(InnerRoomVersionId::Version1),
            "2" => Self(InnerRoomVersionId::Version2),
            "3" => Self(InnerRoomVersionId::Version3),
            "4" => Self(InnerRoomVersionId::Version4),
            "5" => Self(InnerRoomVersionId::Version5),
            custom => {
                if custom.is_empty() {
                    return Err(Error::MinimumLengthNotSatisfied);
                } else if custom.chars().count() > MAX_CODE_POINTS {
                    return Err(Error::MaximumLengthExceeded);
                } else {
                    Self(InnerRoomVersionId::Custom(custom.to_string()))
                }
            }
        };

        Ok(version)
    }
}

impl<'de> Visitor<'de> for RoomVersionIdVisitor {
    type Value = RoomVersionId;

    fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
        write!(formatter, "a Matrix room version ID as a string")
    }

    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
    where
        E: SerdeError,
    {
        match RoomVersionId::try_from(v) {
            Ok(room_id) => Ok(room_id),
            Err(_) => Err(SerdeError::invalid_value(Unexpected::Str(v), &self)),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use serde_json::{from_str, to_string};

    use super::RoomVersionId;
    use crate::error::Error;

    #[test]
    fn valid_version_1_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("1")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "1"
        );
    }

    #[test]
    fn valid_version_2_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("2")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "2"
        );
    }

    #[test]
    fn valid_version_3_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("3")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "3"
        );
    }

    #[test]
    fn valid_version_4_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("4")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "4"
        );
    }

    #[test]
    fn valid_version_5_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("5")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "5"
        );
    }

    #[test]
    fn valid_custom_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("io.ruma.1")
                .expect("Failed to create RoomVersionId.")
                .to_string(),
            "io.ruma.1"
        );
    }

    #[test]
    fn empty_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from(""),
            Err(Error::MinimumLengthNotSatisfied)
        );
    }

    #[test]
    fn over_max_code_point_room_version_id() {
        assert_eq!(
            RoomVersionId::try_from("0123456789012345678901234567890123456789"),
            Err(Error::MaximumLengthExceeded)
        );
    }

    #[test]
    fn serialize_official_room_id() {
        assert_eq!(
            to_string(&RoomVersionId::try_from("1").expect("Failed to create RoomVersionId."))
                .expect("Failed to convert RoomVersionId to JSON."),
            r#""1""#
        );
    }

    #[test]
    fn deserialize_official_room_id() {
        let deserialized =
            from_str::<RoomVersionId>(r#""1""#).expect("Failed to convert RoomVersionId to JSON.");

        assert!(deserialized.is_version_1());
        assert!(deserialized.is_official());

        assert_eq!(
            deserialized,
            RoomVersionId::try_from("1").expect("Failed to create RoomVersionId.")
        );
    }

    #[test]
    fn serialize_custom_room_id() {
        assert_eq!(
            to_string(
                &RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.")
            )
            .expect("Failed to convert RoomVersionId to JSON."),
            r#""io.ruma.1""#
        );
    }

    #[test]
    fn deserialize_custom_room_id() {
        let deserialized = from_str::<RoomVersionId>(r#""io.ruma.1""#)
            .expect("Failed to convert RoomVersionId to JSON.");

        assert!(deserialized.is_custom());

        assert_eq!(
            deserialized,
            RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.")
        );
    }

    #[test]
    fn constructors() {
        assert!(RoomVersionId::version_1().is_version_1());
        assert!(RoomVersionId::version_2().is_version_2());
        assert!(RoomVersionId::version_3().is_version_3());
        assert!(RoomVersionId::version_4().is_version_4());
        assert!(RoomVersionId::version_5().is_version_5());
        assert!(RoomVersionId::custom("foo").is_custom());
    }

    #[test]
    #[allow(clippy::cognitive_complexity)]
    fn predicate_methods() {
        let version_1 = RoomVersionId::try_from("1").expect("Failed to create RoomVersionId.");
        let version_2 = RoomVersionId::try_from("2").expect("Failed to create RoomVersionId.");
        let version_3 = RoomVersionId::try_from("3").expect("Failed to create RoomVersionId.");
        let version_4 = RoomVersionId::try_from("4").expect("Failed to create RoomVersionId.");
        let version_5 = RoomVersionId::try_from("5").expect("Failed to create RoomVersionId.");
        let custom = RoomVersionId::try_from("io.ruma.1").expect("Failed to create RoomVersionId.");

        assert!(version_1.is_version_1());
        assert!(version_2.is_version_2());
        assert!(version_3.is_version_3());
        assert!(version_4.is_version_4());
        assert!(version_5.is_version_5());

        assert!(!version_1.is_version_2());
        assert!(!version_1.is_version_3());
        assert!(!version_1.is_version_4());
        assert!(!version_1.is_version_5());

        assert!(version_1.is_official());
        assert!(version_2.is_official());
        assert!(version_3.is_official());
        assert!(version_4.is_official());
        assert!(version_5.is_official());

        assert!(!version_1.is_custom());
        assert!(!version_2.is_custom());
        assert!(!version_3.is_custom());
        assert!(!version_4.is_custom());
        assert!(!version_5.is_custom());

        assert!(custom.is_custom());
        assert!(!custom.is_official());
        assert!(!custom.is_version_1());
        assert!(!custom.is_version_2());
        assert!(!custom.is_version_3());
        assert!(!custom.is_version_4());
        assert!(!custom.is_version_5());
    }
}
<|endoftext|>


<commit_before><commit_msg>Add RedactionEvent.<commit_after><|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::path::Path;
use std::path::PathBuf;
use std::vec::Vec;
use std::fs::File as FSFile;
use std::fs::create_dir_all;
use std::fs::remove_file;
use std::io::Read;
use std::io::Write;
use std::vec::IntoIter;

use glob::glob;
use glob::Paths;

use storage::file::File;
use storage::file_id::*;
use storage::parser::{FileHeaderParser, Parser, ParserError};

use module::Module;
use runtime::Runtime;

pub type BackendOperationResult<T = ()> = Result<T, StorageBackendError>;

pub struct StorageBackend {
    basepath: String,
    storepath: String,
}

impl StorageBackend {

    pub fn new(rt: &Runtime) -> BackendOperationResult<StorageBackend> {
        let storepath = rt.get_rtp() + "/store/";
        debug!("Trying to create {}", storepath);
        create_dir_all(&storepath).and_then(|_| {
            debug!("Creating succeeded, constructing backend instance");
            Ok(StorageBackend {
                basepath: rt.get_rtp(),
                storepath: storepath.clone(),
            })
        }).or_else(|e| {
            debug!("Creating failed, constructing error instance");
            let mut serr = StorageBackendError::build(
                "create_dir_all()",
                "Could not create store directories",
                Some(storepath)
            );
            serr.caused_by = Some(Box::new(e));
            Err(serr)
        })
    }

    fn get_file_ids(&self, m: &Module) -> Option<Vec<FileID>> {
        let list = glob(&self.prefix_of_files_for_module(m)[..]);

        if let Ok(globlist) = list {
            let mut v = vec![];
            for entry in globlist {
                if let Ok(path) = entry {
                    debug!(" - File: {:?}", path);
                    v.push(from_pathbuf(&path));
                } else {
                    // Entry is not a path
                }
            }

            Some(v)
        } else {
            None
        }
    }

    pub fn iter_ids(&self, m: &Module) -> Option<IntoIter<FileID>>
    {
        glob(&self.prefix_of_files_for_module(m)[..]).and_then(|globlist| {
            let v = globlist.filter_map(Result::ok)
                            .map(|pbuf| from_pathbuf(&pbuf))
                            .collect::<Vec<FileID>>()
                            .into_iter();
            Ok(v)
        }).ok()
    }

    pub fn iter_files<'a, HP>(&self, m: &'a Module, p: &Parser<HP>)
        -> Option<IntoIter<File<'a>>>
        where HP: FileHeaderParser
    {
        self.iter_ids(m).and_then(|ids| {
            Some(ids.filter_map(|id| self.get_file_by_id(m, &id, p))
                    .collect::<Vec<File>>()
                    .into_iter())
        })
    }

    /*
     * Write a file to disk.
     *
     * The file is moved to this function as the file won't be edited afterwards
     */
    pub fn put_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let written = write_with_parser(&f, p);
        if written.is_err() { return Err(written.err().unwrap()); }
        let string = written.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::create(&path).map(|mut file| {
            debug!("Created file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write_all()",
                            "Could not write out File contents",
                            None
                        );
                    err.caused_by = Some(Box::new(ioerr));
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not create file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::create()",
                "Creating file on disk failed",
                None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Update a file. We have the UUID and can find the file on FS with it and
     * then replace its contents with the contents of the passed file object
     */
    pub fn update_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let contents = write_with_parser(&f, p);
        if contents.is_err() { return Err(contents.err().unwrap()); }
        let string = contents.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::open(&path).map(|mut file| {
            debug!("Open file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write()",
                            "Tried to write contents of this file, though operation did not succeed",
                            Some(string)
                        );
                    err.caused_by = Some(Box::new(ioerr));
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not write file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::open()",
                "Tried to update contents of this file, though file doesn't exist",
                None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Find a file by its ID and return it if found. Return nothing if not
     * found, of course.
     *
     * TODO: Needs refactoring, as there might be an error when reading from
     * disk OR the id just does not exist.
     */
    pub fn get_file_by_id<'a, HP>(&self, m: &'a Module, id: &FileID, p: &Parser<HP>) -> Option<File<'a>>
        where HP: FileHeaderParser
    {
        debug!("Searching for file with id '{}'", id);
        if let Ok(mut fs) = FSFile::open(self.build_filepath_with_id(m, id.clone())) {
            let mut s = String::new();
            fs.read_to_string(&mut s);
            debug!("Success reading file with id '{}'", id);
            debug!("Parsing to internal structure now");
            p.read(s).and_then(|(h, d)| Ok(File::from_parser_result(m, id.clone(), h, d))).ok()
        } else {
            debug!("No file with id '{}'", id);
            None
        }
    }

    pub fn remove_file(&self, m: &Module, file: File, checked: bool) -> BackendOperationResult {
        if checked {
            error!("Checked remove not implemented yet. I will crash now");
            unimplemented!()
        }

        debug!("Doing unchecked remove");
        info!("Going to remove file: {}", file);

        let fp = self.build_filepath(&file);
        remove_file(fp).map_err(|e| {
            let mut serr = StorageBackendError::build(
                "remove_file()",
                "File removal failed",
                Some(format!("{}", file))
            );
            serr.caused_by = Some(Box::new(e));
            serr
        })
    }

    fn build_filepath(&self, f: &File) -> String {
        self.build_filepath_with_id(f.owner(), f.id())
    }

    fn build_filepath_with_id(&self, owner: &Module, id: FileID) -> String {
        debug!("Building filepath with id");
        debug!("  basepath: '{}'", self.basepath);
        debug!(" storepath: '{}'", self.storepath);
        debug!("  id      : '{}'", id);
        self.prefix_of_files_for_module(owner) + "-" + &id[..] + ".imag"
    }

    fn prefix_of_files_for_module(&self, m: &Module) -> String {
        self.storepath.clone() + m.name()
    }

}

#[derive(Debug)]
pub struct StorageBackendError {
    pub action: String,             // The file system action in words
    pub desc: String,               // A short description
    pub data_dump: Option<String>,  // Data dump, if any
    pub caused_by: Option<Box<Error>>,  // caused from this error
}

impl StorageBackendError {
    fn new(action: String,
           desc  : String,
           data  : Option<String>) -> StorageBackendError
    {
        StorageBackendError {
            action:         action,
            desc:           desc,
            data_dump:      data,
            caused_by:      None,
        }
    }

    fn build(action: &'static str,
             desc:   &'static str,
             data  : Option<String>) -> StorageBackendError
    {
        StorageBackendError {
            action:         String::from(action),
            desc:           String::from(desc),
            data_dump:      data,
            caused_by:      None,
        }
    }

}

impl Error for StorageBackendError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        self.caused_by.as_ref().map(|e| &**e)
    }

}

impl<'a> Display for StorageBackendError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "StorageBackendError[{}]: {}",
               self.action, self.desc)
    }
}

fn write_with_parser<'a, HP>(f: &File, p: &Parser<HP>) -> Result<String, StorageBackendError>
    where HP: FileHeaderParser
{
    p.write(f.contents())
        .or_else(|err| {
            let mut serr = StorageBackendError::build(
                "Parser::write()",
                "Cannot translate internal representation of file contents into on-disk representation",
                None
            );
            serr.caused_by = Some(Box::new(err));
            Err(serr)
        })
}
<commit_msg>Refactor uses of file-id-parsing functions to ensure we honnor the Result type<commit_after>use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::path::Path;
use std::path::PathBuf;
use std::vec::Vec;
use std::fs::File as FSFile;
use std::fs::create_dir_all;
use std::fs::remove_file;
use std::io::Read;
use std::io::Write;
use std::vec::IntoIter;

use glob::glob;
use glob::Paths;

use storage::file::File;
use storage::file_id::*;
use storage::parser::{FileHeaderParser, Parser, ParserError};

use module::Module;
use runtime::Runtime;

pub type BackendOperationResult<T = ()> = Result<T, StorageBackendError>;

pub struct StorageBackend {
    basepath: String,
    storepath: String,
}

impl StorageBackend {

    pub fn new(rt: &Runtime) -> BackendOperationResult<StorageBackend> {
        let storepath = rt.get_rtp() + "/store/";
        debug!("Trying to create {}", storepath);
        create_dir_all(&storepath).and_then(|_| {
            debug!("Creating succeeded, constructing backend instance");
            Ok(StorageBackend {
                basepath: rt.get_rtp(),
                storepath: storepath.clone(),
            })
        }).or_else(|e| {
            debug!("Creating failed, constructing error instance");
            let mut serr = StorageBackendError::build(
                "create_dir_all()",
                "Could not create store directories",
                Some(storepath)
            );
            serr.caused_by = Some(Box::new(e));
            Err(serr)
        })
    }

    fn get_file_ids(&self, m: &Module) -> Option<Vec<FileID>> {
        let list = glob(&self.prefix_of_files_for_module(m)[..]);

        if let Ok(globlist) = list {
            let mut v = vec![];
            for entry in globlist {
                if let Ok(path) = entry {
                    debug!(" - File: {:?}", path);
                    if let Ok(id) = from_pathbuf(&path) {
                        v.push(id);
                    } else {
                        error!("Cannot parse ID from path: {:?}", path);
                    }
                } else {
                    // Entry is not a path
                }
            }

            Some(v)
        } else {
            None
        }
    }

    pub fn iter_ids(&self, m: &Module) -> Option<IntoIter<FileID>>
    {
        glob(&self.prefix_of_files_for_module(m)[..]).and_then(|globlist| {
            let v = globlist.filter_map(Result::ok)
                            .map(|pbuf| from_pathbuf(&pbuf))
                            .filter_map(Result::ok)
                            .collect::<Vec<FileID>>()
                            .into_iter();
            Ok(v)
        }).ok()
    }

    pub fn iter_files<'a, HP>(&self, m: &'a Module, p: &Parser<HP>)
        -> Option<IntoIter<File<'a>>>
        where HP: FileHeaderParser
    {
        self.iter_ids(m).and_then(|ids| {
            Some(ids.filter_map(|id| self.get_file_by_id(m, &id, p))
                    .collect::<Vec<File>>()
                    .into_iter())
        })
    }

    /*
     * Write a file to disk.
     *
     * The file is moved to this function as the file won't be edited afterwards
     */
    pub fn put_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let written = write_with_parser(&f, p);
        if written.is_err() { return Err(written.err().unwrap()); }
        let string = written.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::create(&path).map(|mut file| {
            debug!("Created file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write_all()",
                            "Could not write out File contents",
                            None
                        );
                    err.caused_by = Some(Box::new(ioerr));
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not create file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::create()",
                "Creating file on disk failed",
                None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Update a file. We have the UUID and can find the file on FS with it and
     * then replace its contents with the contents of the passed file object
     */
    pub fn update_file<HP>(&self, f: File, p: &Parser<HP>) -> BackendOperationResult
        where HP: FileHeaderParser
    {
        let contents = write_with_parser(&f, p);
        if contents.is_err() { return Err(contents.err().unwrap()); }
        let string = contents.unwrap();

        let path = self.build_filepath(&f);
        debug!("Writing file: {}", path);
        debug!("      string: {}", string);

        FSFile::open(&path).map(|mut file| {
            debug!("Open file at '{}'", path);
            file.write_all(&string.clone().into_bytes())
                .map_err(|ioerr| {
                    debug!("Could not write file");
                    let mut err = StorageBackendError::build(
                            "File::write()",
                            "Tried to write contents of this file, though operation did not succeed",
                            Some(string)
                        );
                    err.caused_by = Some(Box::new(ioerr));
                    err
                })
        }).map_err(|writeerr| {
            debug!("Could not write file at '{}'", path);
            let mut err = StorageBackendError::build(
                "File::open()",
                "Tried to update contents of this file, though file doesn't exist",
                None
            );
            err.caused_by = Some(Box::new(writeerr));
            err
        }).and(Ok(()))
    }

    /*
     * Find a file by its ID and return it if found. Return nothing if not
     * found, of course.
     *
     * TODO: Needs refactoring, as there might be an error when reading from
     * disk OR the id just does not exist.
     */
    pub fn get_file_by_id<'a, HP>(&self, m: &'a Module, id: &FileID, p: &Parser<HP>) -> Option<File<'a>>
        where HP: FileHeaderParser
    {
        debug!("Searching for file with id '{}'", id);
        if let Ok(mut fs) = FSFile::open(self.build_filepath_with_id(m, id.clone())) {
            let mut s = String::new();
            fs.read_to_string(&mut s);
            debug!("Success reading file with id '{}'", id);
            debug!("Parsing to internal structure now");
            p.read(s).and_then(|(h, d)| Ok(File::from_parser_result(m, id.clone(), h, d))).ok()
        } else {
            debug!("No file with id '{}'", id);
            None
        }
    }

    pub fn remove_file(&self, m: &Module, file: File, checked: bool) -> BackendOperationResult {
        if checked {
            error!("Checked remove not implemented yet. I will crash now");
            unimplemented!()
        }

        debug!("Doing unchecked remove");
        info!("Going to remove file: {}", file);

        let fp = self.build_filepath(&file);
        remove_file(fp).map_err(|e| {
            let mut serr = StorageBackendError::build(
                "remove_file()",
                "File removal failed",
                Some(format!("{}", file))
            );
            serr.caused_by = Some(Box::new(e));
            serr
        })
    }

    fn build_filepath(&self, f: &File) -> String {
        self.build_filepath_with_id(f.owner(), f.id())
    }

    fn build_filepath_with_id(&self, owner: &Module, id: FileID) -> String {
        debug!("Building filepath with id");
        debug!("  basepath: '{}'", self.basepath);
        debug!(" storepath: '{}'", self.storepath);
        debug!("  id      : '{}'", id);
        self.prefix_of_files_for_module(owner) + "-" + &id[..] + ".imag"
    }

    fn prefix_of_files_for_module(&self, m: &Module) -> String {
        self.storepath.clone() + m.name()
    }

}

#[derive(Debug)]
pub struct StorageBackendError {
    pub action: String,             // The file system action in words
    pub desc: String,               // A short description
    pub data_dump: Option<String>,  // Data dump, if any
    pub caused_by: Option<Box<Error>>,  // caused from this error
}

impl StorageBackendError {
    fn new(action: String,
           desc  : String,
           data  : Option<String>) -> StorageBackendError
    {
        StorageBackendError {
            action:         action,
            desc:           desc,
            data_dump:      data,
            caused_by:      None,
        }
    }

    fn build(action: &'static str,
             desc:   &'static str,
             data  : Option<String>) -> StorageBackendError
    {
        StorageBackendError {
            action:         String::from(action),
            desc:           String::from(desc),
            data_dump:      data,
            caused_by:      None,
        }
    }

}

impl Error for StorageBackendError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        self.caused_by.as_ref().map(|e| &**e)
    }

}

impl<'a> Display for StorageBackendError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "StorageBackendError[{}]: {}",
               self.action, self.desc)
    }
}

fn write_with_parser<'a, HP>(f: &File, p: &Parser<HP>) -> Result<String, StorageBackendError>
    where HP: FileHeaderParser
{
    p.write(f.contents())
        .or_else(|err| {
            let mut serr = StorageBackendError::build(
                "Parser::write()",
                "Cannot translate internal representation of file contents into on-disk representation",
                None
            );
            serr.caused_by = Some(Box::new(err));
            Err(serr)
        })
}
<|endoftext|>


<commit_before><commit_msg>Reexport Tags<commit_after>use structure;

pub mod integer;
pub mod sequence;
pub mod octetstring;
pub mod boolean;
pub mod null;

// Reexport everything
pub use integer::Integer;
pub use sequence::{Sequence, SequenceOf, SetOf};
pub use octetstring::OctetString;
pub use boolean::Boolean;
pub use null::Null;

pub trait ASNTag {
    /// Encode yourself into a generic Tag format.
    ///
    /// The only thing that changes between types is how to encode the value they wrap into bytes,
    /// however the encoding of the class and id does not change. By first converting the tag into
    /// a more generic tag (with already encoded payload), we don't have to reimplement the
    /// encoding step for class & id every time.
    fn into_structure(self) -> structure::StructureTag;
}

#[derive(Clone, Debug)]
/// This enum does not cover all ASN.1 Types but only the types needed for LDAPv3.
pub enum Tag {
    Integer(integer::Integer),
    Sequence(sequence::Sequence),
    OctetString(octetstring::OctetString),
    Boolean(boolean::Boolean),
    Null(null::Null),
    StructureTag(structure::StructureTag),
}

impl ASNTag for Tag {
    fn into_structure(self) -> structure::StructureTag {
        match self {
            Tag::Integer(i)      => i.into_structure(),
            Tag::Sequence(i)     => i.into_structure(),
            Tag::OctetString(i)  => i.into_structure(),
            Tag::Boolean(i)      => i.into_structure(),
            Tag::Null(i)         => i.into_structure(),
            Tag::StructureTag(s) => s
        }
    }
}
<|endoftext|>


<commit_before>#![deny(
    dead_code,
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

#[macro_use] extern crate log;
extern crate toml;
extern crate fs2;

extern crate libimagstore;
extern crate libimagentrylink;
extern crate libimagerror;

pub mod debug;
pub mod flock;
pub mod linkverify;

<commit_msg>Import libimagerror with macros, so we can have own error types internally<commit_after>#![deny(
    dead_code,
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

#[macro_use] extern crate log;
extern crate toml;
extern crate fs2;

extern crate libimagstore;
extern crate libimagentrylink;
#[macro_use] extern crate libimagerror;

pub mod debug;
pub mod flock;
pub mod linkverify;

<|endoftext|>


<commit_before><commit_msg>Add build.rs for codegen module.<commit_after>#![feature(process, path, env)]
use std::process::Command;
use std::env::current_dir;

fn main() {

  assert!(
  	Command::new("clang++")
  		.args(&["tests/test-ir.cc", "-S", "-emit-llvm", "-O2", "-o", "tests/test-ir.ll"])
    	.status()
    	.unwrap()
    	.success()
 	);

}<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            let response: ~str =
                ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

                 \r\n";
            stream.write(response.as_bytes());
            println!("Connection terminates.");
        }
    }
}
<commit_msg>Count works, needs to be displayed in HTML for web page<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();
    let mut visitor_count = 0;

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection

	visitor_count += 1;
	let count = visitor_count;
        println!("Visitor count: {}", visitor_count);

	do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            let response: ~str =
                ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

                 \r\n";
            stream.write(response.as_bytes());
            println!("Connection terminates.");
	    println!("Count: {}", count);
        }
    }
}
<|endoftext|>