<commit_before>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

/*===============================================================================================*/
//! The logging module.
//!
//! It provides basic logging functionality.
/*===============================================================================================*/

extern crate ansi_term;
extern crate log;

use self::ansi_term::Colour::{Blue, White, Yellow, Red};

use std::boxed::Box;
use std::fs::File;
use std::io::BufWriter;
use std::io::prelude::Write;

/*===============================================================================================*/
/*------LOGGER STRUCT----------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The logger struct
///
/// It provides basic logging capabilities, and is designed for use within ion.
pub struct Logger {

    // Private
    log_file: BufWriter <File>,
    log_to_console: bool
}

/*===============================================================================================*/
/*------LOGGER PUBLIC STATIC METHODS-------------------------------------------------------------*/
/*===============================================================================================*/

impl Logger {

    /// Initializes the logger
    ///
    /// This is required before any logging functions are performed.
    /// Any logging done beforehand will be ignored.
    ///
    /// # Arguments
    /// * `log_file_path` - The path to where the log will be saved
    /// * `log_to_console` - Whether the log output should also be printed to the console
    ///
    /// # Return value
    /// A result, returning an error on failure.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::Logger;
    /// #
    /// Logger::init ("LogFile.log", false);
    pub fn init (log_file_path: &str, log_to_console: bool) -> Result<(), log::SetLoggerError> {

        log::set_logger (|max_log_level| {

            if cfg! (debug_assertions) {
                max_log_level.set (log::LogLevelFilter::Debug);
            }

            else {
                max_log_level.set (log::LogLevelFilter::Info);
            }

            Box::new (Logger {log_file: BufWriter::new (File::create (&log_file_path).unwrap ()),
                              log_to_console: log_to_console})
        })
    }
}

/*===============================================================================================*/
/*------LOGGER PRIVATE METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl log::Log for Logger {

    fn enabled (&self, metadata: &log::LogMetadata) -> bool {

        if cfg! (debug_assertions) {
            return metadata.level () <= log::LogLevel::Debug;
        }

        metadata.level () <= log::LogLevel::Info
    }

/*-----------------------------------------------------------------------------------------------*/

    fn log (&self, record: &log::LogRecord) {

        let string_output = format! ("{} ({} : {}) - {}\n", record.level (),
                                                            record.location ().module_path (),
                                                            record.location ().line (),
                                                            record.args ());
        if self.log_to_console {

            match record.level () {

                log::LogLevel::Debug => print! ("{}", Blue.paint (string_output.as_str ())),
                log::LogLevel::Info  => print! ("{}", White.paint (string_output.as_str ())),
                log::LogLevel::Warn  => print! ("{}", Yellow.paint (string_output.as_str ())),
                log::LogLevel::Error => print! ("{}", Red.paint (string_output.as_str ())),
                _ => {}
            }
        }

        self.log_file.get_ref ().write (string_output.as_bytes ()).unwrap ();
    }
}
<commit_msg>Improver logger colour coding<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

/*===============================================================================================*/
//! The logging module.
//!
//! It provides basic logging functionality.
/*===============================================================================================*/

extern crate ansi_term;
extern crate log;

use self::ansi_term::Colour::{Blue, Purple, Yellow, Red};

use std::boxed::Box;
use std::fs::File;
use std::io::BufWriter;
use std::io::prelude::Write;

/*===============================================================================================*/
/*------LOGGER STRUCT----------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The logger struct
///
/// It provides basic logging capabilities, and is designed for use within ion.
pub struct Logger {

    // Private
    log_file: BufWriter <File>,
    log_to_console: bool
}

/*===============================================================================================*/
/*------LOGGER PUBLIC STATIC METHODS-------------------------------------------------------------*/
/*===============================================================================================*/

impl Logger {

    /// Initializes the logger
    ///
    /// This is required before any logging functions are performed.
    /// Any logging done beforehand will be ignored.
    ///
    /// # Arguments
    /// * `log_file_path` - The path to where the log will be saved
    /// * `log_to_console` - Whether the log output should also be printed to the console
    ///
    /// # Return value
    /// A result, returning an error on failure.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::Logger;
    /// #
    /// Logger::init ("LogFile.log", false);
    pub fn init (log_file_path: &str, log_to_console: bool) -> Result<(), log::SetLoggerError> {

        log::set_logger (|max_log_level| {

            if cfg! (debug_assertions) {
                max_log_level.set (log::LogLevelFilter::Debug);
            }

            else {
                max_log_level.set (log::LogLevelFilter::Info);
            }

            Box::new (Logger {log_file: BufWriter::new (File::create (&log_file_path).unwrap ()),
                              log_to_console: log_to_console})
        })
    }
}

/*===============================================================================================*/
/*------LOGGER PRIVATE METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl log::Log for Logger {

    fn enabled (&self, metadata: &log::LogMetadata) -> bool {

        if cfg! (debug_assertions) {
            return metadata.level () <= log::LogLevel::Debug;
        }

        metadata.level () <= log::LogLevel::Info
    }

/*-----------------------------------------------------------------------------------------------*/

    fn log (&self, record: &log::LogRecord) {

        let output = match record.level () {

            log::LogLevel::Debug => format! ("{} ({} : {}) - {}\n", Purple.paint (record.level ().to_string ()),
                                                                    record.location ().module_path (),
                                                                    record.location ().line (),
                                                                    record.args ()),

            log::LogLevel::Info => format! ("{} ({} : {}) - {}\n", Blue.paint (record.level ().to_string ()),
                                                                   record.location ().module_path (),
                                                                   record.location ().line (),
                                                                   record.args ()),

            log::LogLevel::Warn => format! ("{} ({} : {}) - {}\n", Yellow.paint (record.level ().to_string ()),
                                                                   record.location ().module_path (),
                                                                   record.location ().line (),
                                                                   record.args ()),

            log::LogLevel::Error => format! ("{} ({} : {}) - {}\n", Red.paint (record.level ().to_string ()),
                                                                    record.location ().module_path (),
                                                                    record.location ().line (),
                                                                    record.args ()),
            _ => String::new ()
        };

        if self.log_to_console {
            print! ("{}", output);
        }

        self.log_file.get_ref ().write (format! ("{} ({} : {}) - {}\n", record.level (),
                                                                        record.location ().module_path (),
                                                                        record.location ().line (),
                                                                        record.args ()).as_bytes ()).unwrap ();
    }
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//

use std::error::Error;

pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result<u32, String> {
    let (op, pos) = parse_op(mode, Some('='))?;
    mode = mode[pos..].trim_left_matches('0');
    if mode.len() > 4 {
        Err(format!("mode is too large ({} > 7777)", mode))
    } else {
        match u32::from_str_radix(mode, 8) {
            Ok(change) => Ok(match op {
                '+' => fperm | change,
                '-' => fperm & !change,
                '=' => change,
                _ => unreachable!(),
            }),
            Err(err) => Err(err.description().to_owned()),
        }
    }
}

pub fn parse_symbolic(
    mut fperm: u32,
    mut mode: &str,
    considering_dir: bool,
) -> Result<u32, String> {
    #[cfg(unix)]
    use libc::umask;

    #[cfg(target_os = "redox")]
    unsafe fn umask(_mask: u32) -> u32 {
        // XXX Redox does not currently have umask
        0
    }

    let (mask, pos) = parse_levels(mode);
    if pos == mode.len() {
        return Err(format!("invalid mode ({})", mode));
    }
    let respect_umask = pos == 0;
    let last_umask = unsafe { umask(0) };
    mode = &mode[pos..];
    while mode.len() > 0 {
        let (op, pos) = parse_op(mode, None)?;
        mode = &mode[pos..];
        let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
        if respect_umask {
            srwx &= !(last_umask as u32);
        }
        mode = &mode[pos..];
        match op {
            '+' => fperm |= srwx & mask,
            '-' => fperm &= !(srwx & mask),
            '=' => fperm = (fperm & !mask) | (srwx & mask),
            _ => unreachable!(),
        }
    }
    unsafe {
        umask(last_umask);
    }
    Ok(fperm)
}

fn parse_levels(mode: &str) -> (u32, usize) {
    let mut mask = 0;
    let mut pos = 0;
    for ch in mode.chars() {
        mask |= match ch {
            'u' => 0o7700,
            'g' => 0o7070,
            'o' => 0o7007,
            'a' => 0o7777,
            _ => break,
        };
        pos += 1;
    }
    if pos == 0 {
        mask = 0o7777; // default to 'a'
    }
    (mask, pos)
}

fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
    match mode.chars().next() {
        Some(ch) => match ch {
            '+' | '-' | '=' => Ok((ch, 1)),
            _ => match default {
                Some(ch) => Ok((ch, 0)),
                None => Err(format!(
                    "invalid operator (expected +, -, or =, but found {})",
                    ch
                )),
            },
        },
        None => Err("unexpected end of mode".to_owned()),
    }
}

fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) {
    let mut srwx = fperm & 0o7000;
    let mut pos = 0;
    for ch in mode.chars() {
        match ch {
            'r' => srwx |= 0o444,
            'w' => srwx |= 0o222,
            'x' => srwx |= 0o111,
            'X' => {
                if considering_dir || (fperm & 0o0111) != 0 {
                    srwx |= 0o111
                }
            }
            's' => srwx |= 0o4000 | 0o2000,
            't' => srwx |= 0o1000,
            'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
            'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
            'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
            _ => break,
        };
        pos += 1;
    }
    if pos == 0 {
        srwx = 0;
    }
    (srwx, pos)
}
<commit_msg>Get rid of all warnings on Linux (or at least WSL)<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//

use std::error::Error;

pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result<u32, String> {
    let (op, pos) = parse_op(mode, Some('='))?;
    mode = mode[pos..].trim_start_matches('0');
    if mode.len() > 4 {
        Err(format!("mode is too large ({} > 7777)", mode))
    } else {
        match u32::from_str_radix(mode, 8) {
            Ok(change) => Ok(match op {
                '+' => fperm | change,
                '-' => fperm & !change,
                '=' => change,
                _ => unreachable!(),
            }),
            Err(err) => Err(err.description().to_owned()),
        }
    }
}

pub fn parse_symbolic(
    mut fperm: u32,
    mut mode: &str,
    considering_dir: bool,
) -> Result<u32, String> {
    #[cfg(unix)]
    use libc::umask;

    #[cfg(target_os = "redox")]
    unsafe fn umask(_mask: u32) -> u32 {
        // XXX Redox does not currently have umask
        0
    }

    let (mask, pos) = parse_levels(mode);
    if pos == mode.len() {
        return Err(format!("invalid mode ({})", mode));
    }
    let respect_umask = pos == 0;
    let last_umask = unsafe { umask(0) };
    mode = &mode[pos..];
    while mode.len() > 0 {
        let (op, pos) = parse_op(mode, None)?;
        mode = &mode[pos..];
        let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
        if respect_umask {
            srwx &= !(last_umask as u32);
        }
        mode = &mode[pos..];
        match op {
            '+' => fperm |= srwx & mask,
            '-' => fperm &= !(srwx & mask),
            '=' => fperm = (fperm & !mask) | (srwx & mask),
            _ => unreachable!(),
        }
    }
    unsafe {
        umask(last_umask);
    }
    Ok(fperm)
}

fn parse_levels(mode: &str) -> (u32, usize) {
    let mut mask = 0;
    let mut pos = 0;
    for ch in mode.chars() {
        mask |= match ch {
            'u' => 0o7700,
            'g' => 0o7070,
            'o' => 0o7007,
            'a' => 0o7777,
            _ => break,
        };
        pos += 1;
    }
    if pos == 0 {
        mask = 0o7777; // default to 'a'
    }
    (mask, pos)
}

fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
    match mode.chars().next() {
        Some(ch) => match ch {
            '+' | '-' | '=' => Ok((ch, 1)),
            _ => match default {
                Some(ch) => Ok((ch, 0)),
                None => Err(format!(
                    "invalid operator (expected +, -, or =, but found {})",
                    ch
                )),
            },
        },
        None => Err("unexpected end of mode".to_owned()),
    }
}

fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) {
    let mut srwx = fperm & 0o7000;
    let mut pos = 0;
    for ch in mode.chars() {
        match ch {
            'r' => srwx |= 0o444,
            'w' => srwx |= 0o222,
            'x' => srwx |= 0o111,
            'X' => {
                if considering_dir || (fperm & 0o0111) != 0 {
                    srwx |= 0o111
                }
            }
            's' => srwx |= 0o4000 | 0o2000,
            't' => srwx |= 0o1000,
            'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
            'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
            'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
            _ => break,
        };
        pos += 1;
    }
    if pos == 0 {
        srwx = 0;
    }
    (srwx, pos)
}
<|endoftext|>


<commit_before>use std::kinds::marker::ContravariantLifetime;
use std::mem;

use runtime::Object;
use {class, Id, IdVector};
use super::{INSCopying, INSObject};

pub struct NSEnumerator<'a, T> {
	id: Id<Object>,
	marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> {
	unsafe fn from_ptr(ptr: *Object) -> NSEnumerator<'a, T> {
		NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
	}
}

impl<'a, T> Iterator<&'a T> for NSEnumerator<'a, T> {
	fn next(&mut self) -> Option<&'a T> {
		unsafe {
			let obj = msg_send![self.id nextObject];
			if obj.is_null() {
				None
			} else {
				Some(mem::transmute(obj))
			}
		}
	}
}

pub trait INSArray<T: INSObject> : INSObject {
	fn count(&self) -> uint {
		let result = unsafe {
			msg_send![self count]
		};
		result as uint
	}

	fn object_at<'a>(&'a self, index: uint) -> &'a T {
		unsafe {
			let result = msg_send![self objectAtIndex:index];
			mem::transmute(result)
		}
	}

	fn object_enumerator<'a>(&'a self) -> NSEnumerator<'a, T> {
		unsafe {
			let result = msg_send![self objectEnumerator];
			NSEnumerator::from_ptr(result)
		}
	}

	unsafe fn from_refs(refs: &[&T]) -> Id<Self> {
		let cls = class::<Self>();
		let obj = msg_send![cls alloc];
		let obj = msg_send![obj initWithObjects:refs.as_ptr() count:refs.len()];
		Id::from_retained_ptr(obj as *Self)
	}

	fn from_vec(vec: Vec<Id<T>>) -> Id<Self> {
		let refs = vec.as_refs_slice();
		unsafe {
			INSArray::from_refs(refs)
		}
	}
}

object_struct!(NSArray<T>)

impl<T: INSObject> INSArray<T> for NSArray<T> { }

impl<T> INSCopying<NSArray<T>> for NSArray<T> { }

impl<T: INSObject> Collection for NSArray<T> {
	fn len(&self) -> uint {
		self.count()
	}
}
<commit_msg>Added NSArray tests.<commit_after>use std::kinds::marker::ContravariantLifetime;
use std::mem;

use runtime::Object;
use {class, Id, IdVector};
use super::{INSCopying, INSObject};

pub struct NSEnumerator<'a, T> {
	id: Id<Object>,
	marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> {
	unsafe fn from_ptr(ptr: *Object) -> NSEnumerator<'a, T> {
		NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
	}
}

impl<'a, T> Iterator<&'a T> for NSEnumerator<'a, T> {
	fn next(&mut self) -> Option<&'a T> {
		unsafe {
			let obj = msg_send![self.id nextObject];
			if obj.is_null() {
				None
			} else {
				Some(mem::transmute(obj))
			}
		}
	}
}

pub trait INSArray<T: INSObject> : INSObject {
	fn count(&self) -> uint {
		let result = unsafe {
			msg_send![self count]
		};
		result as uint
	}

	fn object_at<'a>(&'a self, index: uint) -> &'a T {
		unsafe {
			let result = msg_send![self objectAtIndex:index];
			mem::transmute(result)
		}
	}

	fn object_enumerator<'a>(&'a self) -> NSEnumerator<'a, T> {
		unsafe {
			let result = msg_send![self objectEnumerator];
			NSEnumerator::from_ptr(result)
		}
	}

	unsafe fn from_refs(refs: &[&T]) -> Id<Self> {
		let cls = class::<Self>();
		let obj = msg_send![cls alloc];
		let obj = msg_send![obj initWithObjects:refs.as_ptr() count:refs.len()];
		Id::from_retained_ptr(obj as *Self)
	}

	fn from_vec(vec: Vec<Id<T>>) -> Id<Self> {
		let refs = vec.as_refs_slice();
		unsafe {
			INSArray::from_refs(refs)
		}
	}
}

object_struct!(NSArray<T>)

impl<T: INSObject> INSArray<T> for NSArray<T> { }

impl<T> INSCopying<NSArray<T>> for NSArray<T> { }

impl<T: INSObject> Collection for NSArray<T> {
	fn len(&self) -> uint {
		self.count()
	}
}

#[cfg(test)]
mod tests {
	use {Id};
	use foundation::{INSObject, NSObject};
	use super::{INSArray, NSArray};

	#[test]
	fn test_count() {
		let empty_array: Id<NSArray<NSObject>> = INSObject::new();
		assert!(empty_array.count() == 0);

		let vec: Vec<Id<NSObject>> = Vec::from_fn(4, |_| INSObject::new());
		let array: Id<NSArray<NSObject>> = INSArray::from_vec(vec);
		assert!(array.count() == 4);
	}

	#[test]
	fn test_object_at() {
		let vec: Vec<Id<NSObject>> = Vec::from_fn(4, |_| INSObject::new());
		let array: Id<NSArray<NSObject>> = INSArray::from_vec(vec);
		assert!(array.object_at(0) != array.object_at(3));
	}

	#[test]
	fn test_object_enumerator() {
		let vec: Vec<Id<NSObject>> = Vec::from_fn(4, |_| INSObject::new());
		let array: Id<NSArray<NSObject>> = INSArray::from_vec(vec);

		assert!(array.object_enumerator().count() == 4);
		assert!(array.object_enumerator()
		             .enumerate()
		             .all(|(i, obj)| obj == array.object_at(i)));
	}
}
<|endoftext|>


<commit_before>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cxx::{memory::UniquePtrTarget, UniquePtr};
use moveit::{CopyNew, DerefMove, MoveNew, New};
use std::{marker::PhantomPinned, mem::MaybeUninit, ops::Deref, pin::Pin};

/// A trait representing a parameter to a C++ function which is received
/// by value.
///
/// Rust has the concept of receiving parameters by _move_ or by _reference_.
/// C++ has the concept of receiving a parameter by 'value', which means
/// the parameter gets copied.
///
/// To make it easy to pass such parameters from Rust, this trait exists.
/// It is implemented both for references `&T` and for `UniquePtr<T>`,
/// subject to the presence or absence of suitable copy and move constructors.
/// This allows you to pass in parameters by copy (as is ergonomic and normal
/// in C++) retaining the original parameter; or by move semantics thus
/// destroying the object you're passing in. Simply use a reference if you want
/// copy semantics, or the item itself if you want move semantics.
///
/// It is not recommended that you implement this trait, nor that you directly
/// use its methods, which are for use by `autocxx` generated code only.
///
/// # Use of `moveit` traits
///
/// Most of the implementations of this trait require the type to implement
/// [`CopyNew`], which is simply the `autocxx`/`moveit` way of saying that
/// the type has a copy constructor in C++.
///
/// # Being explicit
///
/// If you wish to explicitly force either a move or a copy of some type,
/// use [`as_mov`] or [`as_copy`].
///
/// # Performance
///
/// At present, some additional copying occurs for all implementations of
/// this trait other than that for [`cxx::UniquePtr`]. In the future it's
/// hoped that the implementation for `&T where T: CopyNew` can also avoid
/// this extra copying.
///
/// # Panics
///
/// The implementations of this trait which take a [`cxx::UniquePtr`] will
/// panic if the pointer is NULL.
///
/// # Safety
///
/// Implementers must guarantee that the pointer returned by `get_ptr`
/// is of the correct size and alignment of `T`.
pub unsafe trait ValueParam<T> {
    /// Any stack storage required. If, as part of passing to C++,
    /// we need to store a temporary copy of the value, this will be `T`,
    /// otherwise `()`.
    #[doc(hidden)]
    type StackStorage;
    /// Populate the stack storage given as a parameter. Only called if you
    /// return `true` from `needs_stack_space`.
    ///
    /// # Safety
    ///
    /// Callers must guarantee that this object will not move in memory
    /// between this call and any subsequent `get_ptr` call or drop.
    #[doc(hidden)]
    unsafe fn populate_stack_space(self, this: Pin<&mut Option<Self::StackStorage>>);
    /// Retrieve the pointer to the underlying item, to be passed to C++.
    /// Note that on the C++ side this is currently passed to `std::move`
    /// and therefore may be mutated.
    #[doc(hidden)]
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T;
    #[doc(hidden)]
    /// Any special drop steps required for the stack storage. This is not
    /// necessary if the `StackStorage` type is something self-dropping
    /// such as `UniquePtr`; it's only necessary if it's something where
    /// manual management is required such as `MaybeUninit`.
    fn do_drop(_stack: Pin<&mut Self::StackStorage>) {}
}

unsafe impl<T> ValueParam<T> for &T
where
    T: CopyNew,
{
    type StackStorage = MaybeUninit<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we won't move/swap things within the pin.
        let slot = Pin::into_inner_unchecked(stack.as_mut());
        *slot = Some(MaybeUninit::uninit());
        crate::moveit::new::copy(self).new(Pin::new_unchecked(slot.as_mut().unwrap()))
    }
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: it's OK to (briefly) create a reference to the T because we
        // populated it within `populate_stack_space`. It's OK to unpack the pin
        // because we're not going to move the contents.
        unsafe { Pin::into_inner_unchecked(stack).assume_init_mut() as *mut T }
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        // Switch to MaybeUninit::assume_init_drop when stabilized
        // Safety: per caller guarantees of populate_stack_space, we know this hasn't moved.
        unsafe { std::ptr::drop_in_place(Pin::into_inner_unchecked(stack).assume_init_mut()) };
    }
}

unsafe impl<T> ValueParam<T> for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type StackStorage = UniquePtr<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we will not move the contents of the pin.
        *Pin::into_inner_unchecked(stack.as_mut()) = Some(self)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: we won't move/swap the contents of the outer pin, nor of the
        // type stored within the UniquePtr.
        unsafe {
            (Pin::into_inner_unchecked(
                (*Pin::into_inner_unchecked(stack))
                    .as_mut()
                    .expect("Passed a NULL UniquePtr as a C++ value parameter"),
            )) as *mut T
        }
    }
}

unsafe impl<T> ValueParam<T> for Pin<Box<T>> {
    type StackStorage = Pin<Box<T>>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we will not move the contents of the pin.
        *Pin::into_inner_unchecked(stack.as_mut()) = Some(self)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: we won't move/swap the contents of the outer pin, nor of the
        // type stored within the UniquePtr.
        unsafe {
            (Pin::into_inner_unchecked((*Pin::into_inner_unchecked(stack)).as_mut())) as *mut T
        }
    }
}

unsafe impl<'a, T: 'a> ValueParam<T> for &'a UniquePtr<T>
where
    T: UniquePtrTarget + CopyNew,
{
    type StackStorage = <&'a T as ValueParam<T>>::StackStorage;

    unsafe fn populate_stack_space(self, stack: Pin<&mut Option<Self::StackStorage>>) {
        self.as_ref()
            .expect("Passed a NULL &UniquePtr as a C++ value parameter")
            .populate_stack_space(stack)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        <&'a T as ValueParam<T>>::get_ptr(stack)
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        <&'a T as ValueParam<T>>::do_drop(stack)
    }
}

unsafe impl<'a, T: 'a> ValueParam<T> for &'a Pin<Box<T>>
where
    T: CopyNew,
{
    type StackStorage = <&'a T as ValueParam<T>>::StackStorage;

    unsafe fn populate_stack_space(self, stack: Pin<&mut Option<Self::StackStorage>>) {
        self.as_ref()
            .get_ref()
            .populate_stack_space(stack)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        <&'a T as ValueParam<T>>::get_ptr(stack)
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        <&'a T as ValueParam<T>>::do_drop(stack)
    }
}

/// Explicitly force a value parameter to be taken using any type of [`crate::moveit::new::New`],
/// i.e. a constructor.
pub fn as_new<N: New<Output = T>, T>(constructor: N) -> impl ValueParam<T> {
    ByNew(constructor)
}

/// Explicitly force a value parameter to be taken by copy.
pub fn as_copy<P: Deref<Target = T>, T>(ptr: P) -> impl ValueParam<T>
where
    T: CopyNew,
{
    ByNew(crate::moveit::new::copy(ptr))
}

/// Explicitly force a value parameter to be taken usign C++ move semantics.
pub fn as_mov<P: DerefMove + Deref<Target = T>, T>(ptr: P) -> impl ValueParam<T>
where
    P: DerefMove,
    P::Target: MoveNew,
{
    ByNew(crate::moveit::new::mov(ptr))
}

#[doc(hidden)]
pub struct ByNew<N: New>(N);

unsafe impl<N, T> ValueParam<T> for ByNew<N>
where
    N: New<Output = T>,
{
    type StackStorage = MaybeUninit<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we won't move/swap things within the pin.
        let slot = Pin::into_inner_unchecked(stack.as_mut());
        *slot = Some(MaybeUninit::uninit());
        self.0.new(Pin::new_unchecked(slot.as_mut().unwrap()))
    }
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: it's OK to (briefly) create a reference to the T because we
        // populated it within `populate_stack_space`. It's OK to unpack the pin
        // because we're not going to move the contents.
        unsafe { Pin::into_inner_unchecked(stack).assume_init_mut() as *mut T }
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        // Switch to MaybeUninit::assume_init_drop when stabilized
        // Safety: per caller guarantees of populate_stack_space, we know this hasn't moved.
        unsafe { std::ptr::drop_in_place(Pin::into_inner_unchecked(stack).assume_init_mut()) };
    }
}

/// Implementation detail for how we pass value parameters into C++.
/// This type is instantiated by auto-generated autocxx code each time we
/// need to pass a value parameter into C++, and will take responsibility
/// for extracting that value parameter from the [`ValueParam`] and doing
/// any later cleanup.
#[doc(hidden)]
pub struct ValueParamHandler<T, VP: ValueParam<T>> {
    // We can't populate this on 'new' because the object may move.
    // Hence this is an Option - it's None until populate is called.
    space: Option<VP::StackStorage>,
    _pinned: PhantomPinned,
}

impl<T, VP: ValueParam<T>> ValueParamHandler<T, VP> {
    /// Populate this stack space if needs be. Note safety guarantees
    /// on [`get_ptr`].
    ///
    /// # Safety
    ///
    /// Callers must call [`populate`] exactly once prior to calling [`get_ptr`].
    pub unsafe fn populate(self: Pin<&mut Self>, param: VP) {
        // Structural pinning, as documented in [`std::pin`].
        param.populate_stack_space(self.map_unchecked_mut(|s| &mut s.space))
    }

    /// Return a pointer to the underlying value which can be passed to C++.
    ///
    /// Per the unsafety contract of [`populate`], [`populate`] has been called exactly once
    /// prior to this call.
    pub fn get_ptr(self: Pin<&mut Self>) -> *mut T {
        // Structural pinning, as documented in [`std::pin`]. `map_unchecked_mut` doesn't play
        // nicely with `unwrap`, so we have to do it manually.
        unsafe {
            VP::get_ptr(Pin::new_unchecked(
                self.get_unchecked_mut().space.as_mut().unwrap(),
            ))
        }
    }
}

impl<T, VP: ValueParam<T>> Default for ValueParamHandler<T, VP> {
    fn default() -> Self {
        Self {
            space: None,
            _pinned: PhantomPinned,
        }
    }
}

impl<T, VP: ValueParam<T>> Drop for ValueParamHandler<T, VP> {
    fn drop(&mut self) {
        if let Some(space) = self.space.as_mut() {
            unsafe { VP::do_drop(Pin::new_unchecked(space)) }
        }
    }
}
<commit_msg>Format<commit_after>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cxx::{memory::UniquePtrTarget, UniquePtr};
use moveit::{CopyNew, DerefMove, MoveNew, New};
use std::{marker::PhantomPinned, mem::MaybeUninit, ops::Deref, pin::Pin};

/// A trait representing a parameter to a C++ function which is received
/// by value.
///
/// Rust has the concept of receiving parameters by _move_ or by _reference_.
/// C++ has the concept of receiving a parameter by 'value', which means
/// the parameter gets copied.
///
/// To make it easy to pass such parameters from Rust, this trait exists.
/// It is implemented both for references `&T` and for `UniquePtr<T>`,
/// subject to the presence or absence of suitable copy and move constructors.
/// This allows you to pass in parameters by copy (as is ergonomic and normal
/// in C++) retaining the original parameter; or by move semantics thus
/// destroying the object you're passing in. Simply use a reference if you want
/// copy semantics, or the item itself if you want move semantics.
///
/// It is not recommended that you implement this trait, nor that you directly
/// use its methods, which are for use by `autocxx` generated code only.
///
/// # Use of `moveit` traits
///
/// Most of the implementations of this trait require the type to implement
/// [`CopyNew`], which is simply the `autocxx`/`moveit` way of saying that
/// the type has a copy constructor in C++.
///
/// # Being explicit
///
/// If you wish to explicitly force either a move or a copy of some type,
/// use [`as_mov`] or [`as_copy`].
///
/// # Performance
///
/// At present, some additional copying occurs for all implementations of
/// this trait other than that for [`cxx::UniquePtr`]. In the future it's
/// hoped that the implementation for `&T where T: CopyNew` can also avoid
/// this extra copying.
///
/// # Panics
///
/// The implementations of this trait which take a [`cxx::UniquePtr`] will
/// panic if the pointer is NULL.
///
/// # Safety
///
/// Implementers must guarantee that the pointer returned by `get_ptr`
/// is of the correct size and alignment of `T`.
pub unsafe trait ValueParam<T> {
    /// Any stack storage required. If, as part of passing to C++,
    /// we need to store a temporary copy of the value, this will be `T`,
    /// otherwise `()`.
    #[doc(hidden)]
    type StackStorage;
    /// Populate the stack storage given as a parameter. Only called if you
    /// return `true` from `needs_stack_space`.
    ///
    /// # Safety
    ///
    /// Callers must guarantee that this object will not move in memory
    /// between this call and any subsequent `get_ptr` call or drop.
    #[doc(hidden)]
    unsafe fn populate_stack_space(self, this: Pin<&mut Option<Self::StackStorage>>);
    /// Retrieve the pointer to the underlying item, to be passed to C++.
    /// Note that on the C++ side this is currently passed to `std::move`
    /// and therefore may be mutated.
    #[doc(hidden)]
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T;
    #[doc(hidden)]
    /// Any special drop steps required for the stack storage. This is not
    /// necessary if the `StackStorage` type is something self-dropping
    /// such as `UniquePtr`; it's only necessary if it's something where
    /// manual management is required such as `MaybeUninit`.
    fn do_drop(_stack: Pin<&mut Self::StackStorage>) {}
}

unsafe impl<T> ValueParam<T> for &T
where
    T: CopyNew,
{
    type StackStorage = MaybeUninit<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we won't move/swap things within the pin.
        let slot = Pin::into_inner_unchecked(stack.as_mut());
        *slot = Some(MaybeUninit::uninit());
        crate::moveit::new::copy(self).new(Pin::new_unchecked(slot.as_mut().unwrap()))
    }
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: it's OK to (briefly) create a reference to the T because we
        // populated it within `populate_stack_space`. It's OK to unpack the pin
        // because we're not going to move the contents.
        unsafe { Pin::into_inner_unchecked(stack).assume_init_mut() as *mut T }
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        // Switch to MaybeUninit::assume_init_drop when stabilized
        // Safety: per caller guarantees of populate_stack_space, we know this hasn't moved.
        unsafe { std::ptr::drop_in_place(Pin::into_inner_unchecked(stack).assume_init_mut()) };
    }
}

unsafe impl<T> ValueParam<T> for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type StackStorage = UniquePtr<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we will not move the contents of the pin.
        *Pin::into_inner_unchecked(stack.as_mut()) = Some(self)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: we won't move/swap the contents of the outer pin, nor of the
        // type stored within the UniquePtr.
        unsafe {
            (Pin::into_inner_unchecked(
                (*Pin::into_inner_unchecked(stack))
                    .as_mut()
                    .expect("Passed a NULL UniquePtr as a C++ value parameter"),
            )) as *mut T
        }
    }
}

unsafe impl<T> ValueParam<T> for Pin<Box<T>> {
    type StackStorage = Pin<Box<T>>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we will not move the contents of the pin.
        *Pin::into_inner_unchecked(stack.as_mut()) = Some(self)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: we won't move/swap the contents of the outer pin, nor of the
        // type stored within the UniquePtr.
        unsafe {
            (Pin::into_inner_unchecked((*Pin::into_inner_unchecked(stack)).as_mut())) as *mut T
        }
    }
}

unsafe impl<'a, T: 'a> ValueParam<T> for &'a UniquePtr<T>
where
    T: UniquePtrTarget + CopyNew,
{
    type StackStorage = <&'a T as ValueParam<T>>::StackStorage;

    unsafe fn populate_stack_space(self, stack: Pin<&mut Option<Self::StackStorage>>) {
        self.as_ref()
            .expect("Passed a NULL &UniquePtr as a C++ value parameter")
            .populate_stack_space(stack)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        <&'a T as ValueParam<T>>::get_ptr(stack)
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        <&'a T as ValueParam<T>>::do_drop(stack)
    }
}

unsafe impl<'a, T: 'a> ValueParam<T> for &'a Pin<Box<T>>
where
    T: CopyNew,
{
    type StackStorage = <&'a T as ValueParam<T>>::StackStorage;

    unsafe fn populate_stack_space(self, stack: Pin<&mut Option<Self::StackStorage>>) {
        self.as_ref().get_ref().populate_stack_space(stack)
    }

    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        <&'a T as ValueParam<T>>::get_ptr(stack)
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        <&'a T as ValueParam<T>>::do_drop(stack)
    }
}

/// Explicitly force a value parameter to be taken using any type of [`crate::moveit::new::New`],
/// i.e. a constructor.
pub fn as_new<N: New<Output = T>, T>(constructor: N) -> impl ValueParam<T> {
    ByNew(constructor)
}

/// Explicitly force a value parameter to be taken by copy.
pub fn as_copy<P: Deref<Target = T>, T>(ptr: P) -> impl ValueParam<T>
where
    T: CopyNew,
{
    ByNew(crate::moveit::new::copy(ptr))
}

/// Explicitly force a value parameter to be taken usign C++ move semantics.
pub fn as_mov<P: DerefMove + Deref<Target = T>, T>(ptr: P) -> impl ValueParam<T>
where
    P: DerefMove,
    P::Target: MoveNew,
{
    ByNew(crate::moveit::new::mov(ptr))
}

#[doc(hidden)]
pub struct ByNew<N: New>(N);

unsafe impl<N, T> ValueParam<T> for ByNew<N>
where
    N: New<Output = T>,
{
    type StackStorage = MaybeUninit<T>;

    unsafe fn populate_stack_space(self, mut stack: Pin<&mut Option<Self::StackStorage>>) {
        // Safety: we won't move/swap things within the pin.
        let slot = Pin::into_inner_unchecked(stack.as_mut());
        *slot = Some(MaybeUninit::uninit());
        self.0.new(Pin::new_unchecked(slot.as_mut().unwrap()))
    }
    fn get_ptr(stack: Pin<&mut Self::StackStorage>) -> *mut T {
        // Safety: it's OK to (briefly) create a reference to the T because we
        // populated it within `populate_stack_space`. It's OK to unpack the pin
        // because we're not going to move the contents.
        unsafe { Pin::into_inner_unchecked(stack).assume_init_mut() as *mut T }
    }

    fn do_drop(stack: Pin<&mut Self::StackStorage>) {
        // Switch to MaybeUninit::assume_init_drop when stabilized
        // Safety: per caller guarantees of populate_stack_space, we know this hasn't moved.
        unsafe { std::ptr::drop_in_place(Pin::into_inner_unchecked(stack).assume_init_mut()) };
    }
}

/// Implementation detail for how we pass value parameters into C++.
/// This type is instantiated by auto-generated autocxx code each time we
/// need to pass a value parameter into C++, and will take responsibility
/// for extracting that value parameter from the [`ValueParam`] and doing
/// any later cleanup.
#[doc(hidden)]
pub struct ValueParamHandler<T, VP: ValueParam<T>> {
    // We can't populate this on 'new' because the object may move.
    // Hence this is an Option - it's None until populate is called.
    space: Option<VP::StackStorage>,
    _pinned: PhantomPinned,
}

impl<T, VP: ValueParam<T>> ValueParamHandler<T, VP> {
    /// Populate this stack space if needs be. Note safety guarantees
    /// on [`get_ptr`].
    ///
    /// # Safety
    ///
    /// Callers must call [`populate`] exactly once prior to calling [`get_ptr`].
    pub unsafe fn populate(self: Pin<&mut Self>, param: VP) {
        // Structural pinning, as documented in [`std::pin`].
        param.populate_stack_space(self.map_unchecked_mut(|s| &mut s.space))
    }

    /// Return a pointer to the underlying value which can be passed to C++.
    ///
    /// Per the unsafety contract of [`populate`], [`populate`] has been called exactly once
    /// prior to this call.
    pub fn get_ptr(self: Pin<&mut Self>) -> *mut T {
        // Structural pinning, as documented in [`std::pin`]. `map_unchecked_mut` doesn't play
        // nicely with `unwrap`, so we have to do it manually.
        unsafe {
            VP::get_ptr(Pin::new_unchecked(
                self.get_unchecked_mut().space.as_mut().unwrap(),
            ))
        }
    }
}

impl<T, VP: ValueParam<T>> Default for ValueParamHandler<T, VP> {
    fn default() -> Self {
        Self {
            space: None,
            _pinned: PhantomPinned,
        }
    }
}

impl<T, VP: ValueParam<T>> Drop for ValueParamHandler<T, VP> {
    fn drop(&mut self) {
        if let Some(space) = self.space.as_mut() {
            unsafe { VP::do_drop(Pin::new_unchecked(space)) }
        }
    }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::fmt::{Debug, Formatter, Error as FmtError};

use toml::Value;

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;

pub struct CreateHook<'a> {
    storepath: &'a PathBuf,

    position: HookPosition,
    config: Option<Value>,
}

impl<'a> CreateHook<'a> {

    pub fn new(storepath: &'a PathBuf, p: HookPosition) -> CreateHook<'a> {
        CreateHook {
            storepath: storepath,
            position: p,
            config: None,
        }
    }

}

impl<'a> Debug for CreateHook<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
        write!(fmt, "CreateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.repository.is_some() { "Some(_)" } else { "None" }),
               self.position,
               self.config)
    }
}

impl<'a> Hook for CreateHook<'a> {

    fn name(&self) -> &'static str {
        "stdhook_git_create"
    }

    fn set_config(&mut self, config: &Value) {
        self.config = Some(config.clone());
    }

}

impl<'a> HookDataAccessorProvider for CreateHook<'a> {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl<'a> StoreIdAccessor for CreateHook<'a> {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[GIT CREATE HOOK]: {:?}", id);
        Ok(())
    }

}

<commit_msg>Add Repository instantiation<commit_after>use std::path::PathBuf;
use std::fmt::{Debug, Formatter, Error as FmtError};

use toml::Value;
use git2::{Repository, Error as Git2Error};

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagerror::trace::trace_error;

pub struct CreateHook<'a> {
    storepath: &'a PathBuf,

    repository: Option<Repository>,

    position: HookPosition,
    config: Option<Value>,
}

impl<'a> CreateHook<'a> {

    pub fn new(storepath: &'a PathBuf, p: HookPosition) -> CreateHook<'a> {
        let r = match Repository::open(storepath) {
            Ok(r) => Some(r),
            Err(e) => {
                trace_error(&e);
                None
            },
        };
        CreateHook {
            storepath: storepath,
            repository: r,
            position: p,
            config: None,
        }
    }

}

impl<'a> Debug for CreateHook<'a> {

    fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
        write!(fmt, "CreateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.repository.is_some() { "Some(_)" } else { "None" }),
               self.position,
               self.config)
    }
}

impl<'a> Hook for CreateHook<'a> {

    fn name(&self) -> &'static str {
        "stdhook_git_create"
    }

    fn set_config(&mut self, config: &Value) {
        self.config = Some(config.clone());
    }

}

impl<'a> HookDataAccessorProvider for CreateHook<'a> {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl<'a> StoreIdAccessor for CreateHook<'a> {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[GIT CREATE HOOK]: {:?}", id);
        Ok(())
    }

}

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

//error-pattern: no mir for `std::panicking::panicking`

use std::sync::Mutex;

fn par_for<I, F>(iter: I, f: F)
    where I: Iterator,
          I::Item: Send,
          F: Fn(I::Item) + Sync
{
    for item in iter {
        f(item)
    }
}

fn sum(x: &[i32]) {
    let sum_lengths = Mutex::new(0);
    par_for(x.windows(4), |x| {
        *sum_lengths.lock().unwrap() += x.len()
    });

    assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4);
}

fn main() {
    let mut elements = [0; 20];

    // iterators over references into this stack frame
    par_for(elements.iter_mut().enumerate(), |(i, x)| {
        *x = i as i32
    });

    sum(&elements)
}
<commit_msg>msvc has different internals for mutexes and thus fails on a different function<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.

//error-pattern: no mir for `std::

use std::sync::Mutex;

fn par_for<I, F>(iter: I, f: F)
    where I: Iterator,
          I::Item: Send,
          F: Fn(I::Item) + Sync
{
    for item in iter {
        f(item)
    }
}

fn sum(x: &[i32]) {
    let sum_lengths = Mutex::new(0);
    par_for(x.windows(4), |x| {
        *sum_lengths.lock().unwrap() += x.len()
    });

    assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4);
}

fn main() {
    let mut elements = [0; 20];

    // iterators over references into this stack frame
    par_for(elements.iter_mut().enumerate(), |(i, x)| {
        *x = i as i32
    });

    sum(&elements)
}
<|endoftext|>


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


<commit_before><commit_msg>clippy: Fix write/writeln warnings.<commit_after><|endoftext|>


<commit_before><commit_msg>Document the primary DOM<commit_after><|endoftext|>


<commit_before><commit_msg>Add another TODO.<commit_after><|endoftext|>


<commit_before><commit_msg>docs: reduce the need to guess<commit_after><|endoftext|>


<commit_before><commit_msg>load symlinks<commit_after><|endoftext|>


<commit_before><commit_msg>Fix publshed/published typo<commit_after><|endoftext|>


<commit_before><commit_msg>Added comments to introsort<commit_after><|endoftext|>


<commit_before><commit_msg>rustdoc<commit_after><|endoftext|>


<commit_before>use super::MessageAction;
use super::MessageActionBuilder;
use config::action::ExecCondition;

use handlebars::Template;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &String) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        match Template::compile(template_string) {
            Ok(message) => Ok(message),
            Err(error) => {
                return Err(Error::syntax(&format!("Invalid handlebars template in 'message' \
                                                   field: uuid={}, error={}",
                                                  &uuid,
                                                  error)));
            }
        }
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();

        loop {
            match try!(visitor.visit_key()) {
                Some(Field::Name) => {
                    name = Some(try!(visitor.visit_value()));
                }
                Some(Field::Uuid) => {
                    uuid = Some(try!(visitor.visit_value()));
                }
                Some(Field::Message) => {
                    message = Some(try!(visitor.visit_value()));
                }
                Some(Field::Values) => {
                    values = Some(try!(visitor.visit_value()));
                }
                Some(Field::When) => {
                    when = try!(visitor.visit_value());
                }
                None => {
                    break;
                }
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => {
                try!(MessageActionVisitor::compile_template::<V>(message, &uuid))
            }
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let values = match values {
            Some(values) => {
                let mut converted_values = BTreeMap::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    converted_values.insert(key, template);
                }
                converted_values
            }
            None => BTreeMap::new(),
        };

        try!(visitor.end());

        Ok(MessageActionBuilder::new(uuid, message)
                                .name(name)
                                .values(values)
                                .when(when)
                                .build())
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction};

    use handlebars::Template;
    use serde_json::from_str;

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }
}
<commit_msg>InjectMode: impl Deserialize<commit_after>use super::MessageAction;
use super::MessageActionBuilder;
use super::InjectMode;
use config::action::ExecCondition;

use handlebars::Template;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &String) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        match Template::compile(template_string) {
            Ok(message) => Ok(message),
            Err(error) => {
                return Err(Error::syntax(&format!("Invalid handlebars template in 'message' \
                                                   field: uuid={}, error={}",
                                                  &uuid,
                                                  error)));
            }
        }
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();

        loop {
            match try!(visitor.visit_key()) {
                Some(Field::Name) => {
                    name = Some(try!(visitor.visit_value()));
                }
                Some(Field::Uuid) => {
                    uuid = Some(try!(visitor.visit_value()));
                }
                Some(Field::Message) => {
                    message = Some(try!(visitor.visit_value()));
                }
                Some(Field::Values) => {
                    values = Some(try!(visitor.visit_value()));
                }
                Some(Field::When) => {
                    when = try!(visitor.visit_value());
                }
                None => {
                    break;
                }
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => {
                try!(MessageActionVisitor::compile_template::<V>(message, &uuid))
            }
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let values = match values {
            Some(values) => {
                let mut converted_values = BTreeMap::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    converted_values.insert(key, template);
                }
                converted_values
            }
            None => BTreeMap::new(),
        };

        try!(visitor.end());

        Ok(MessageActionBuilder::new(uuid, message)
                                .name(name)
                                .values(values)
                                .when(when)
                                .build())
    }
}

impl Deserialize for InjectMode {
    fn deserialize<D>(deserializer: &mut D) -> Result<InjectMode, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = InjectMode;

            fn visit_str<E>(&mut self, value: &str) -> Result<InjectMode, E>
                where E: Error
            {
                match value {
                    "log" => Ok(InjectMode::Log),
                    "loopback" => Ok(InjectMode::Loopback),
                    "forward" => Ok(InjectMode::Forward),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction, InjectMode};

    use handlebars::Template;
    use serde_json::from_str;

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_string())
                         .ok()
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_string())
                          .ok()
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let message = result.ok().expect("Failed to deserialize a valid MessageAction object");
        assert_eq!(expected_message, message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }

    #[test]
    fn test_given_inject_modes_when_they_are_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["forward", "log", "loopback", "log"]
        "#;
        let expected = vec![InjectMode::Forward, InjectMode::Log, InjectMode::Loopback, InjectMode::Log];

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let array = result.ok().expect("Failed to deserialize a valid array of inject modes");
        assert_eq!(&expected, &array);
    }

    #[test]
    fn test_given_invalid_inject_mode_when_it_is_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["invalid inject mode", "log"]
        "#;

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid inject mode");
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::num::{Int, UnsignedInt, NumCast, cast};
use std::collections;
use std::slice;

use alphabets::{Alphabet, RankTransform};

fn qgram_push<Q: UnsignedInt + NumCast>(qgram: &mut Q, a: u8) {
    *qgram = *qgram << 2; // TODO generalize this for n-bit encoding!
    *qgram = *qgram | cast(a).unwrap();
    // TODO mask unused bits with q
}

struct QGrams<'a, Q: UnsignedInt + NumCast> {
    text: slice::Iter<'a, u8>,
    qgram: Q,
    q: usize,
    ranks: RankTransform,
}

impl<'a, Q: UnsignedInt + NumCast> QGrams<'a, Q> {
    pub fn new(q: usize, text: &'a [u8], alphabet: &Alphabet) -> Self {
        let ranks = RankTransform::new(alphabet);
        let mut qgrams = QGrams { text: text.iter(), qgram: cast(0).unwrap(), q: q, ranks: ranks };
        for _ in 0..q-1 {
            qgrams.next();
        }

        qgrams
    }
}

impl<'a, Q: UnsignedInt + NumCast> Iterator for QGrams<'a, Q> {
    type Item = Q;

    fn next(&mut self) -> Option<Q> {
        match self.text.next() {
            Some(a) => {
                qgram_push(&mut self.qgram, self.ranks.get(*a));
                Some(self.qgram)
            },
            None    => None
        }
    }
}

pub struct QGramIndex<'a> {
    q: usize,
    alphabet: &'a Alphabet,
    address: Vec<usize>,
    pos: Vec<usize>,
}

impl<'a> QGramIndex<'a> {
    pub fn new(q: usize, text: &[u8], alphabet: &'a Alphabet) -> Self {
        let qgram_count = alphabet.len().pow(q as u32);
        let mut address = vec![0; qgram_count];
        let mut pos = vec![0; text.len()];

        for qgram in QGrams::<u32>::new(q, text, alphabet) {
            address[qgram as usize] += 1;
        }

        for i in 1..address.len() {
            address[i] += address[i - 1];
        }

        {
            let mut offset = vec![0; qgram_count];
            for (i, qgram) in QGrams::<u32>::new(q, text, alphabet).enumerate() {
                pos[address[qgram as usize] + offset[qgram as usize]] = i;
                offset[qgram as usize] += 1;
            }
        }

        QGramIndex { q: q, alphabet: alphabet, address: address, pos: pos }
    }

    pub fn matches(&self, qgram: u32) -> &[usize] {
        &self.pos[self.address[qgram as usize]..self.address[qgram as usize + 1]]
    }

    pub fn diagonals(&self, pattern: &[u8]) -> Vec<Diagonal> {
        let mut diagonals = collections::HashMap::new();
        for (i, qgram) in QGrams::<u32>::new(self.q, pattern, self.alphabet).enumerate() {
            for p in self.matches(qgram) {
                let diagonal = p - i;
                if diagonals.contains_key(&diagonal) {
                    diagonals.insert(diagonal, 1);
                }
                else {
                    *diagonals.get_mut(&diagonal).unwrap() += 1;
                }
            }
        }
        diagonals.into_iter().map(|(diagonal, count)| Diagonal { pos: diagonal, count: count }).collect()
    }

    pub fn exact_matches(&self, pattern: &[u8]) -> Vec<ExactMatch> {
        let mut diagonals: collections::HashMap<usize, ExactMatch> = collections::HashMap::new();
        let mut intervals = Vec::new();
        for (i, qgram) in QGrams::<u32>::new(self.q, pattern, self.alphabet).enumerate() {
            for &p in self.matches(qgram) {
                let diagonal = p - i;
                if !diagonals.contains_key(&diagonal) {
                    // nothing yet, start new match
                    diagonals.insert(diagonal, ExactMatch {
                            pattern_start: i,
                            pattern_stop: i + self.q,
                            text_start: p,
                            text_stop: p + self.q
                    });
                }
                else {
                    let mut interval = diagonals.get_mut(&diagonal).unwrap();
                    if interval.pattern_stop == i {
                        // extend exact match
                        interval.pattern_stop = i + self.q;
                        interval.text_stop = p + self.q;
                    }
                    else {
                        // report previous match
                        intervals.push(*interval);
                        // mismatch or indel, start new match
                        interval.pattern_start = i;
                        interval.pattern_stop = i + self.q;
                        interval.text_start = p;
                        interval.text_stop = p + self.q;
                    }

                }
            }
        }
        // report remaining intervals
        for (diagonal, interval) in diagonals.into_iter() {
            intervals.push(interval);
        }
        intervals
    }
}

pub struct Diagonal {
    pos: usize,
    count: usize,
}

#[derive(Copy)]
pub struct ExactMatch {
    pub pattern_start: usize,
    pub pattern_stop: usize,
    pub text_start: usize,
    pub text_stop: usize,
}
<commit_msg>Refactoring.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::num::{Int, UnsignedInt, NumCast, cast, Float};
use std::collections;
use std::slice;
use std;

use alphabets::{Alphabet, RankTransform};

struct QGrams<'a, Q: UnsignedInt + NumCast> {
    text: slice::Iter<'a, u8>,
    qgram: Q,
    bits: usize,
    mask: Q,
    ranks: RankTransform,
}

impl<'a, Q: UnsignedInt + NumCast> QGrams<'a, Q> {
    pub fn new(q: usize, text: &'a [u8], alphabet: &Alphabet) -> Self {
        let ranks = RankTransform::new(alphabet);
        let mut qgrams = QGrams {
            text: text.iter(),
            qgram: cast(0).unwrap(),
            ranks: ranks,
            bits: (alphabet.len() as f32).log2().ceil() as usize,
            mask: cast((1 << q) - 1).unwrap(),
        };
        for _ in 0..q-1 {
            qgrams.next();
        }

        qgrams
    }

    fn qgram_push(&mut self, a: u8) {
        self.qgram = self.qgram << self.bits;
        self.qgram = (self.qgram | cast(a).unwrap()) & self.mask;
    }
}

impl<'a, Q: UnsignedInt + NumCast> Iterator for QGrams<'a, Q> {
    type Item = Q;

    fn next(&mut self) -> Option<Q> {
        match self.text.next() {
            Some(a) => {
                let b = self.ranks.get(*a);
                self.qgram_push(b);
                Some(self.qgram)
            },
            None    => None
        }
    }
}

pub struct QGramIndex<'a> {
    q: usize,
    alphabet: &'a Alphabet,
    address: Vec<usize>,
    pos: Vec<usize>,
}

impl<'a> QGramIndex<'a> {
    pub fn new(q: usize, text: &[u8], alphabet: &'a Alphabet) -> Self {
        QGramIndex::with_max_count(q, text, alphabet, std::usize::MAX)
    }

    pub fn with_max_count(q: usize, text: &[u8], alphabet: &'a Alphabet, max_count: usize) -> Self {
        let qgram_count = alphabet.len().pow(q as u32);
        let mut address = vec![0; qgram_count + 1];
        let mut pos = vec![0; text.len()];

        for qgram in QGrams::<u32>::new(q, text, alphabet) {
            address[qgram as usize] += 1;
        }

        for g in 1..address.len() {
            if address[g] > max_count {
                // mask qgram
                address[g] = 0;
            }
        }

        for i in 1..address.len() {
            address[i] += address[i - 1];
        }

        {
            let mut offset = vec![0; qgram_count];
            for (i, qgram) in QGrams::<u32>::new(q, text, alphabet).enumerate() {
                let a = address[qgram as usize];
                if address[qgram as usize + 1] - a != 0 {
                    // if not masked, insert positions
                    pos[a + offset[qgram as usize]] = i;
                    offset[qgram as usize] += 1;
                }
            }
        }

        QGramIndex { q: q, alphabet: alphabet, address: address, pos: pos }
    }

    pub fn matches(&self, qgram: u32) -> &[usize] {
        &self.pos[self.address[qgram as usize]..self.address[qgram as usize + 1]]
    }

    pub fn diagonals(&self, pattern: &[u8]) -> Vec<Diagonal> {
        let mut diagonals = collections::HashMap::new();
        for (i, qgram) in QGrams::<u32>::new(self.q, pattern, self.alphabet).enumerate() {
            for p in self.matches(qgram) {
                let diagonal = p - i;
                if diagonals.contains_key(&diagonal) {
                    diagonals.insert(diagonal, 1);
                }
                else {
                    *diagonals.get_mut(&diagonal).unwrap() += 1;
                }
            }
        }
        diagonals.into_iter().map(|(diagonal, count)| Diagonal { pos: diagonal, count: count }).collect()
    }

    pub fn exact_matches(&self, pattern: &[u8]) -> Vec<ExactMatch> {
        let mut diagonals: collections::HashMap<usize, ExactMatch> = collections::HashMap::new();
        let mut intervals = Vec::new();
        for (i, qgram) in QGrams::<u32>::new(self.q, pattern, self.alphabet).enumerate() {
            for &p in self.matches(qgram) {
                let diagonal = p - i;
                if !diagonals.contains_key(&diagonal) {
                    // nothing yet, start new match
                    diagonals.insert(diagonal, ExactMatch {
                            pattern_start: i,
                            pattern_stop: i + self.q,
                            text_start: p,
                            text_stop: p + self.q
                    });
                }
                else {
                    let interval = diagonals.get_mut(&diagonal).unwrap();
                    if interval.pattern_stop == i {
                        // extend exact match
                        interval.pattern_stop = i + self.q;
                        interval.text_stop = p + self.q;
                    }
                    else {
                        // report previous match
                        intervals.push(*interval);
                        // mismatch or indel, start new match
                        interval.pattern_start = i;
                        interval.pattern_stop = i + self.q;
                        interval.text_start = p;
                        interval.text_stop = p + self.q;
                    }

                }
            }
        }
        // report remaining intervals
        for (_, interval) in diagonals.into_iter() {
            intervals.push(interval);
        }
        intervals
    }
}

pub struct Diagonal {
    pub pos: usize,
    pub count: usize,
}

#[derive(Copy)]
pub struct ExactMatch {
    pub pattern_start: usize,
    pub pattern_stop: usize,
    pub text_start: usize,
    pub text_stop: usize,
}
<|endoftext|>


<commit_before>//! Implementation of build script for all Qt crates
//!
//! See [README](https://github.com/rust-qt/cpp_to_rust)
//! for more information.

use itertools::Itertools;
use qt_ritual_common::get_full_build_config;
use ritual_build::common::errors::{FancyUnwrap, Result};
use ritual_build::common::target::current_target;
use ritual_build::common::utils::MapIfOk;
use ritual_build::Config;
use semver::Version;

#[allow(clippy::op_ref)] // false positive
fn detect_closest_version(known: &[&str], current: &str) -> Result<Option<String>> {
    let known = known.map_if_ok(|i| Version::parse(i))?;
    let current = Version::parse(current)?;

    if known.contains(&current) {
        return Ok(Some(current.to_string()));
    }

    let same_patch = known
        .iter()
        .filter(|v| v.major == current.major && v.minor == current.minor)
        .collect_vec();

    if !same_patch.is_empty() {
        if let Some(version) = same_patch.iter().filter(|&&v| v < &current).max() {
            return Ok(Some(version.to_string()));
        }
        return Ok(Some(same_patch.iter().min().unwrap().to_string()));
    }

    if let Some(version) = known.iter().filter(|&v| v < &current).max() {
        return Ok(Some(version.to_string()));
    } else {
        return Ok(None);
    }
}

/// Runs the build script.
pub fn run_and_return(crate_name: &str) -> Result<()> {
    let qt_config = get_full_build_config(crate_name, None)?;

    let mut config = Config::new()?;

    let current_target = current_target();
    let known_library_versions = config
        .known_targets()
        .iter()
        .filter(|item| item.target == current_target)
        .map(|item| {
            item.cpp_library_version
                .as_ref()
                .expect("qt crates should always have reported library version")
                .as_str()
        })
        .collect_vec();

    if known_library_versions.contains(&qt_config.installation_data.qt_version.as_str()) {
        config.set_current_cpp_library_version(Some(qt_config.installation_data.qt_version));
    } else {
        match detect_closest_version(
            &known_library_versions,
            &qt_config.installation_data.qt_version,
        ) {
            Ok(Some(version)) => {
                println!(
                    "cargo:warning=Current Qt version ({}) is unknown to {} crate. \
                     Using closest known version ({})",
                    qt_config.installation_data.qt_version, crate_name, version
                );
                config.set_current_cpp_library_version(Some(version));
            }
            Ok(None) => {
                println!("This crate supports the following targets:");
                for target in config.known_targets() {
                    println!("* {}", target.short_text());
                }
                panic!(
                    "Unsupported Qt version: {}",
                    qt_config.installation_data.qt_version
                );
            }
            Err(error) => {
                println!(
                    "cargo:warning=Error while choosing known version: {}",
                    error
                );
            }
        }
    }

    config.set_cpp_build_config(qt_config.cpp_build_config);
    config.set_cpp_build_paths(qt_config.cpp_build_paths);
    config.run_and_return()
}

/// Runs the build script and exits the process with an appropriate exit code.
pub fn run(crate_name: &str) -> ! {
    run_and_return(crate_name).fancy_unwrap();
    std::process::exit(0);
}

#[test]
fn versions() {
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.12.2"], "5.13.1").unwrap(),
        Some("5.12.2".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.9.1").unwrap(),
        Some("5.9.7".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.10.7", "5.12.2"], "5.9.1").unwrap(),
        None
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.10.1").unwrap(),
        Some("5.9.7".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.11.2").unwrap(),
        Some("5.11.0".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.2", "5.9.7", "5.12.2"], "5.11.0").unwrap(),
        Some("5.11.2".to_string())
    );
}
<commit_msg>don't enforce known target in build script<commit_after>//! Implementation of build script for all Qt crates
//!
//! See [README](https://github.com/rust-qt/cpp_to_rust)
//! for more information.

use itertools::Itertools;
use qt_ritual_common::get_full_build_config;
use ritual_build::common::errors::{FancyUnwrap, Result};
use ritual_build::common::utils::MapIfOk;
use ritual_build::Config;
use semver::Version;

#[allow(clippy::op_ref)] // false positive
fn detect_closest_version(known: &[&str], current: &str) -> Result<Option<String>> {
    let known = known.map_if_ok(|i| Version::parse(i))?;
    let current = Version::parse(current)?;

    if known.contains(&current) {
        return Ok(Some(current.to_string()));
    }

    let same_patch = known
        .iter()
        .filter(|v| v.major == current.major && v.minor == current.minor)
        .collect_vec();

    if !same_patch.is_empty() {
        if let Some(version) = same_patch.iter().filter(|&&v| v < &current).max() {
            return Ok(Some(version.to_string()));
        }
        return Ok(Some(same_patch.iter().min().unwrap().to_string()));
    }

    if let Some(version) = known.iter().filter(|&v| v < &current).max() {
        return Ok(Some(version.to_string()));
    } else {
        return Ok(None);
    }
}

/// Runs the build script.
pub fn run_and_return(crate_name: &str) -> Result<()> {
    let qt_config = get_full_build_config(crate_name, None)?;

    let mut config = Config::new()?;

    let known_library_versions = config
        .known_targets()
        .iter()
        .map(|item| {
            item.cpp_library_version
                .as_ref()
                .expect("qt crates should always have reported library version")
                .as_str()
        })
        .collect_vec();

    if known_library_versions.contains(&qt_config.installation_data.qt_version.as_str()) {
        config.set_current_cpp_library_version(Some(qt_config.installation_data.qt_version));
    } else {
        match detect_closest_version(
            &known_library_versions,
            &qt_config.installation_data.qt_version,
        ) {
            Ok(Some(version)) => {
                println!(
                    "cargo:warning=Current Qt version ({}) is unknown to {} crate. \
                     Using closest known version ({})",
                    qt_config.installation_data.qt_version, crate_name, version
                );
                config.set_current_cpp_library_version(Some(version));
            }
            Ok(None) => {
                println!("This crate supports the following targets:");
                for target in config.known_targets() {
                    println!("* {}", target.short_text());
                }
                panic!(
                    "Unsupported Qt version: {}",
                    qt_config.installation_data.qt_version
                );
            }
            Err(error) => {
                println!(
                    "cargo:warning=Error while choosing known version: {}",
                    error
                );
            }
        }
    }

    config.set_cpp_build_config(qt_config.cpp_build_config);
    config.set_cpp_build_paths(qt_config.cpp_build_paths);
    config.run_and_return()
}

/// Runs the build script and exits the process with an appropriate exit code.
pub fn run(crate_name: &str) -> ! {
    run_and_return(crate_name).fancy_unwrap();
    std::process::exit(0);
}

#[test]
fn versions() {
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.12.2"], "5.13.1").unwrap(),
        Some("5.12.2".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.9.1").unwrap(),
        Some("5.9.7".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.10.7", "5.12.2"], "5.9.1").unwrap(),
        None
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.10.1").unwrap(),
        Some("5.9.7".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.0", "5.9.7", "5.12.2"], "5.11.2").unwrap(),
        Some("5.11.0".to_string())
    );
    assert_eq!(
        detect_closest_version(&["5.11.2", "5.9.7", "5.12.2"], "5.11.0").unwrap(),
        Some("5.11.2".to_string())
    );
}
<|endoftext|>


<commit_before>/* Part of srtcli */
use std::fmt;

pub struct Subtitle {
    seq: i64,
    start: i64,
    end: i64,
    text: String,
}

impl Subtitle {
    pub fn new(seq: i64, start: i64, end: i64, text: &str) -> Subtitle {
        Subtitle {
            seq: seq,
            start: start,
            end: end,
            text: text.to_string(),
        }
    }
    pub fn get_start(&self) -> i64 {
        self.start
    }
    pub fn get_end(&self) -> i64 {
        self.end
    }
    pub fn get_text(&self) -> &str {
        &self.text
    }
}

impl fmt::Display for Subtitle {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Subtitle #{} ({} -> {}): {}",
        self.seq, self.start, self.end, self.text)
    }
}
<commit_msg>Update subtitle.rs<commit_after>use std::fmt;

pub struct Subtitle {
    seq: i64,
    start: i64,
    end: i64,
    text: String,
}

impl Subtitle {
    pub fn new(seq: i64, start: i64, end: i64, text: &str) -> Subtitle {
        Subtitle {
            seq: seq,
            start: start,
            end: end,
            text: text.to_string(),
        }
    }
    pub fn get_start(&self) -> i64 {
        self.start
    }
    pub fn get_end(&self) -> i64 {
        self.end
    }
    pub fn get_text(&self) -> &str {
        &self.text
    }
}

impl fmt::Display for Subtitle {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Subtitle #{} ({} -> {}): {}",
        self.seq, self.start, self.end, self.text)
    }
}
<|endoftext|>


<commit_before>
fn print_gurobi_confs() {
  use std::env;
  use std::path::{Path, PathBuf};

  let gurobi_home = env::var("GUROBI_HOME").unwrap();
  assert!(Path::new(gurobi_home.as_str()).exists());

  let mut libpath: PathBuf = PathBuf::from(gurobi_home);
  libpath.push("lib");

  println!("cargo:rustc-link-search=native={}", libpath.to_str().unwrap());
}

fn main() {
  print_gurobi_confs();

  println!("cargo:rustc-link-lib={}", "gurobi65")
}
<commit_msg>estimate the version of gurobi at compile time<commit_after>use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

fn gurobi_home() -> String {
  let gurobi_home = env::var("GUROBI_HOME").unwrap();
  assert!(Path::new(gurobi_home.as_str()).exists());
  gurobi_home
}

fn append_path(addpath: &str) {
  if let Some(path) = env::var_os("PATH") {
    let mut paths = env::split_paths(&path).collect::<Vec<_>>();
    paths.push(PathBuf::from(addpath));
    let new_path = env::join_paths(paths).unwrap();
    env::set_var("PATH", &new_path);
  }
}

fn get_version_triple() -> (i32, i32, i32) {
  let mut binpath = PathBuf::from(gurobi_home());
  binpath.push("bin");
  append_path(binpath.to_str().unwrap());

  let output = Command::new("gurobi_cl").arg("--version").output().expect("failed to execute gurobi_cl");
  let verno: Vec<_> = String::from_utf8(output.stdout)
    .unwrap()
    .split_whitespace()
    .nth(3)
    .unwrap()
    .split(".")
    .map(|s| s.parse().unwrap())
    .collect();

  (verno[0], verno[1], verno[2])
}

fn main() {
  let mut libpath: PathBuf = PathBuf::from(gurobi_home());
  libpath.push("lib");
  let libpath = libpath.to_str().unwrap();

  let (major, minor, _) = get_version_triple();
  let libname = format!("gurobi{}{}", major, minor);

  println!("cargo:rustc-link-search=native={}", libpath);
  println!("cargo:rustc-link-lib={}", libname);
}
<|endoftext|>


<commit_before>#![cfg(test)]

use std::collections::HashMap;
use rustc_serialize::json;
use rustc_serialize::json::{decode, Json, Object};
use rustc_serialize::{Decoder, Decodable};
use std::io::prelude::*;
use std::fs::File;
use token::{Token, ReservedWord};

pub struct ExpectPass {
    source: String,
    expected: Json,
    options: Option<Json>
}

pub struct ExpectFail {
    source: String,
    error: String,
    options: Option<Json>
}

pub enum TestCase {
    Pass(ExpectPass),
    Fail(ExpectFail)
}

trait JsonExt {
    fn into_array(self) -> json::Array;
    fn into_string(self) -> String;
    fn into_string_opt(self) -> Option<String>;
}

impl JsonExt for Json {
    fn into_array(self) -> json::Array {
        match self {
            Json::Array(array) => array,
            _ => panic!("expected array")
        }
    }
    fn into_string(self) -> String {
        match self {
            Json::String(string) => string,
            _ => panic!("expected string")
        }
    }
    fn into_string_opt(self) -> Option<String> {
        match self {
            Json::Null => None,
            Json::String(string) => Some(string),
            _ => panic!("expected string or null")
        }
    }
}

fn parse_expect_fail(test: &mut Object) -> ExpectFail {
    ExpectFail {
        source: test.remove("source").unwrap().into_string(),
        error: test.remove("error").unwrap().into_string(),
        options: None
    }
}

fn parse_expect_pass(test: &mut Object) -> ExpectPass {
    ExpectPass {
        source: test.remove("source").unwrap().into_string(),
        expected: test.remove("expected").unwrap(),
        options: None
    }
}

trait Matcher {
    fn test(self: Box<Self>, arg: &mut Object) -> Option<Token>;
}

impl<F> Matcher for F
    where F: FnOnce(&mut Object) -> Option<Token>
{
    fn test(self: Box<F>, arg: &mut Object) -> Option<Token> {
        self(arg)
    }
}

fn matcher<F:FnOnce(&mut Object) -> Option<Token> + 'static>(f: F) -> Box<Matcher> {
    Box::new(f)
}

fn nullary(token: Token) -> Box<Matcher> {
    matcher(|_| { Some(token) })
}

fn unary_string<F:Fn(String) -> Token + 'static>(f: F) -> Box<Matcher> {
    matcher(move |data| {
        data.remove("value")
            .map(|str| f(str.into_string()))
    })
}

fn deserialize_token(mut data: Json) -> Token {
    let mut obj = data.as_object_mut().unwrap();
    let ty = obj.remove("type").unwrap().into_string();

    let mut matchers: HashMap<&str, Box<Matcher>> = HashMap::new();
    matchers.insert("LBrace", nullary(Token::LBrace));
    matchers.insert("DecimalInt", matcher(|data| -> Option<Token> {
        match data.remove("value") {
            None => None,
            Some(str) => Some(Token::DecimalInt(str.into_string()))
        }
    }));
    matchers.insert("String", unary_string(Token::String));

    let f = matchers.remove("DecimalInt").unwrap();
    let mut data = Json::from_str("{\"type\":\"DecimalInt\",\"value\":\"11.3\"}").unwrap();
    let obj = data.as_object_mut().unwrap();
    f.test(obj).unwrap()
}

fn parse_test(mut test: Json) -> TestCase {
    let obj = test.as_object_mut().unwrap();
    if obj.contains_key("error") {
        TestCase::Fail(parse_expect_fail(obj))
    } else {
        TestCase::Pass(parse_expect_pass(obj))
    }
}

pub fn read_tests(path: &str) -> Vec<TestCase> {
    let mut f: File = File::open(path).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s);
    parse_tests(&s)
}

pub fn parse_tests(src: &str) -> Vec<TestCase> {
    let data: Json = src.parse().unwrap();
    data.into_array()
        .into_iter()
        .map(parse_test)
        .collect()
}
<commit_msg>augh, I realized I could borrow the contents of the string and then just use declarative pattern matching<commit_after>#![cfg(test)]

use std::collections::HashMap;
use rustc_serialize::json;
use rustc_serialize::json::{decode, Json, Object};
use rustc_serialize::{Decoder, Decodable};
use std::io::prelude::*;
use std::fs::File;
use token::{Token, ReservedWord};

pub struct ExpectPass {
    source: String,
    expected: Json,
    options: Option<Json>
}

pub struct ExpectFail {
    source: String,
    error: String,
    options: Option<Json>
}

pub enum TestCase {
    Pass(ExpectPass),
    Fail(ExpectFail)
}

trait JsonExt {
    fn into_array(self) -> json::Array;
    fn into_string(self) -> String;
    fn into_string_opt(self) -> Option<String>;
}

impl JsonExt for Json {
    fn into_array(self) -> json::Array {
        match self {
            Json::Array(array) => array,
            _ => panic!("expected array")
        }
    }
    fn into_string(self) -> String {
        match self {
            Json::String(string) => string,
            _ => panic!("expected string")
        }
    }
    fn into_string_opt(self) -> Option<String> {
        match self {
            Json::Null => None,
            Json::String(string) => Some(string),
            _ => panic!("expected string or null")
        }
    }
}

fn parse_expect_fail(test: &mut Object) -> ExpectFail {
    ExpectFail {
        source: test.remove("source").unwrap().into_string(),
        error: test.remove("error").unwrap().into_string(),
        options: None
    }
}

fn parse_expect_pass(test: &mut Object) -> ExpectPass {
    ExpectPass {
        source: test.remove("source").unwrap().into_string(),
        expected: test.remove("expected").unwrap(),
        options: None
    }
}

fn deserialize_token(mut data: Json) -> Token {
    let mut obj = data.as_object_mut().unwrap();
    let ty = obj.remove("type").unwrap().into_string();

    match &ty[..] {
        "LBrace"        => Token::LBrace,
        "DecimalInt"    => Token::DecimalInt(obj.remove("value").unwrap().into_string()),
        "String"        => Token::String(obj.remove("value").unwrap().into_string()),
        _               => panic!("invalid token")
    }
}

fn parse_test(mut test: Json) -> TestCase {
    let obj = test.as_object_mut().unwrap();
    if obj.contains_key("error") {
        TestCase::Fail(parse_expect_fail(obj))
    } else {
        TestCase::Pass(parse_expect_pass(obj))
    }
}

pub fn read_tests(path: &str) -> Vec<TestCase> {
    let mut f: File = File::open(path).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s);
    parse_tests(&s)
}

pub fn parse_tests(src: &str) -> Vec<TestCase> {
    let data: Json = src.parse().unwrap();
    data.into_array()
        .into_iter()
        .map(parse_test)
        .collect()
}
<|endoftext|>