<commit_before>use std::f64;
use std::ops::{Add, Sub, Mul, Div};

#[derive(Clone, Copy)]
pub enum Parameter {
    Fixed(f64),
    Exponential {
        init: f64,
        floor: f64,
        count: u32,
        decay: f64,
    },
    Polynomial {
        init: f64,
        floor: f64,
        count: u32,
        exponent: f64,
    }
}

impl Parameter {
    pub fn fixed(value: f64) -> Self {
        Parameter::Fixed(value)
    }

    pub fn exponential(init: f64, decay: f64, floor: f64) -> Self {
        Parameter::Exponential {
            init: init,
            floor: floor,
            count: 0,
            decay: decay,
        }
    }

    pub fn polynomial(init: f64, exponent: f64, floor: f64) -> Self {
        Parameter::Polynomial {
            init: init,
            floor: floor,
            count: 0,
            exponent: exponent,
        }
    }

    pub fn value(&self) -> f64 {
        match self {
            &Parameter::Fixed(v) => v,

            &Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => f64::max(i * d.powf(c as f64), f),

            &Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => f64::max(i * (c as f64).powf(e), f),
        }
    }

    pub fn step(self) -> Self {
        match self {
            Parameter::Fixed(_) => self,
            Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => Parameter::Exponential {
                init: i,
                floor: f,
                count: c + 1,
                decay: d,
            },
            Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => Parameter::Polynomial {
                init: i,
                floor: f,
                count: c + 1,
                exponent: e,
            },
        }
    }

    pub fn back(self) -> Self {
        match self {
            Parameter::Fixed(_) => self,
            Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => Parameter::Exponential {
                init: i,
                floor: f,
                count: c - 1,
                decay: d,
            },
            Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => Parameter::Polynomial {
                init: i,
                floor: f,
                count: c - 1,
                exponent: e,
            },
        }
    }
}

impl Into<Parameter> for f64 {
    fn into(self) -> Parameter {
        Parameter::Fixed(self)
    }
}

macro_rules! impl_op {
    ($name: ident, $num_type: ty, $fn_name: ident, $op: tt) => {
        impl $name<$num_type> for Parameter {
            type Output = $num_type;

            fn $fn_name(self, other: $num_type) -> $num_type {
                self.value() $op other
            }
        }

        impl $name<Parameter> for $num_type {
            type Output = $num_type;

            fn $fn_name(self, other: Parameter) -> $num_type {
                self $op other.value()
            }
        }

        impl $name<Parameter> for Parameter {
            type Output = $num_type;

            fn $fn_name(self, other: Parameter) -> $num_type {
                self.value() $op other.value()
            }
        }
    }
}

impl_op!(Add, f64, add, +);
impl_op!(Sub, f64, sub, -);
impl_op!(Mul, f64, mul, *);
impl_op!(Div, f64, div, /);

// TODO: Add tests
<commit_msg>Add Parameter method to_fixed<commit_after>use std::f64;
use std::ops::{Add, Sub, Mul, Div};

#[derive(Clone, Copy)]
pub enum Parameter {
    Fixed(f64),
    Exponential {
        init: f64,
        floor: f64,
        count: u32,
        decay: f64,
    },
    Polynomial {
        init: f64,
        floor: f64,
        count: u32,
        exponent: f64,
    }
}

impl Parameter {
    pub fn fixed(value: f64) -> Parameter {
        Parameter::Fixed(value)
    }

    pub fn exponential(init: f64, decay: f64, floor: f64) -> Parameter {
        Parameter::Exponential {
            init: init,
            floor: floor,
            count: 0,
            decay: decay,
        }
    }

    pub fn polynomial(init: f64, exponent: f64, floor: f64) -> Parameter {
        Parameter::Polynomial {
            init: init,
            floor: floor,
            count: 0,
            exponent: exponent,
        }
    }

    pub fn value(&self) -> f64 {
        match self {
            &Parameter::Fixed(v) => v,

            &Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => f64::max(i * d.powf(c as f64), f),

            &Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => f64::max(i * (c as f64).powf(e), f),
        }
    }

    pub fn to_fixed(self) -> Parameter {
        Parameter::Fixed(self.value())
    }

    pub fn step(self) -> Parameter {
        match self {
            Parameter::Fixed(_) => self,
            Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => Parameter::Exponential {
                init: i,
                floor: f,
                count: c + 1,
                decay: d,
            },
            Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => Parameter::Polynomial {
                init: i,
                floor: f,
                count: c + 1,
                exponent: e,
            },
        }
    }

    pub fn back(self) -> Parameter {
        match self {
            Parameter::Fixed(_) => self,
            Parameter::Exponential {
                init: i, floor: f, count: c, decay: d
            } => Parameter::Exponential {
                init: i,
                floor: f,
                count: c - 1,
                decay: d,
            },
            Parameter::Polynomial {
                init: i, floor: f, count: c, exponent: e
            } => Parameter::Polynomial {
                init: i,
                floor: f,
                count: c - 1,
                exponent: e,
            },
        }
    }
}

impl Into<Parameter> for f64 {
    fn into(self) -> Parameter {
        Parameter::Fixed(self)
    }
}

macro_rules! impl_op {
    ($name: ident, $num_type: ty, $fn_name: ident, $op: tt) => {
        impl $name<$num_type> for Parameter {
            type Output = $num_type;

            fn $fn_name(self, other: $num_type) -> $num_type {
                self.value() $op other
            }
        }

        impl $name<Parameter> for $num_type {
            type Output = $num_type;

            fn $fn_name(self, other: Parameter) -> $num_type {
                self $op other.value()
            }
        }

        impl $name<Parameter> for Parameter {
            type Output = $num_type;

            fn $fn_name(self, other: Parameter) -> $num_type {
                self.value() $op other.value()
            }
        }
    }
}

impl_op!(Add, f64, add, +);
impl_op!(Sub, f64, sub, -);
impl_op!(Mul, f64, mul, *);
impl_op!(Div, f64, div, /);

// TODO: Add tests
<|endoftext|>


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

#![allow(dead_code, missing_docs, bad_style)]

use io::{self, ErrorKind};

pub mod args;
pub mod backtrace;
pub mod condvar;
pub mod env;
pub mod ext;
pub mod fast_thread_local;
pub mod fd;
pub mod fs;
pub mod memchr;
pub mod mutex;
pub mod net;
pub mod os;
pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
pub mod rand;
pub mod rt;
pub mod rwlock;
pub mod stack_overflow;
pub mod stdio;
pub mod syscall;
pub mod thread;
pub mod thread_local;
pub mod time;

#[cfg(not(test))]
pub fn init() {
    use alloc::oom;

    oom::set_oom_handler(oom_handler);

    // A nicer handler for out-of-memory situations than the default one. This
    // one prints a message to stderr before aborting. It is critical that this
    // code does not allocate any memory since we are in an OOM situation. Any
    // errors are ignored while printing since there's nothing we can do about
    // them and we are about to exit anyways.
    fn oom_handler() -> ! {
        use intrinsics;
        let msg = "fatal runtime error: out of memory\n";
        unsafe {
            let _ = syscall::write(2, msg.as_bytes());
            intrinsics::abort();
        }
    }
}

pub fn decode_error_kind(errno: i32) -> ErrorKind {
    match errno {
        syscall::ECONNREFUSED => ErrorKind::ConnectionRefused,
        syscall::ECONNRESET => ErrorKind::ConnectionReset,
        syscall::EPERM | syscall::EACCES => ErrorKind::PermissionDenied,
        syscall::EPIPE => ErrorKind::BrokenPipe,
        syscall::ENOTCONN => ErrorKind::NotConnected,
        syscall::ECONNABORTED => ErrorKind::ConnectionAborted,
        syscall::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
        syscall::EADDRINUSE => ErrorKind::AddrInUse,
        syscall::ENOENT => ErrorKind::NotFound,
        syscall::EINTR => ErrorKind::Interrupted,
        syscall::EINVAL => ErrorKind::InvalidInput,
        syscall::ETIMEDOUT => ErrorKind::TimedOut,
        syscall::EEXIST => ErrorKind::AlreadyExists,

        // These two constants can have the same value on some systems,
        // but different values on others, so we can't use a match
        // clause
        x if x == syscall::EAGAIN || x == syscall::EWOULDBLOCK =>
            ErrorKind::WouldBlock,

        _ => ErrorKind::Other,
    }
}

pub fn cvt(result: Result<usize, syscall::Error>) -> io::Result<usize> {
    result.map_err(|err| io::Error::from_raw_os_error(err.errno))
}

/// On Redox, use an illegal instruction to abort
pub unsafe fn abort_internal() -> ! {
    ::core::intrinsics::abort();
}
<commit_msg>Fix building without backtrace<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code, missing_docs, bad_style)]

use io::{self, ErrorKind};

pub mod args;
#[cfg(any(not(cargobuild), feature = "backtrace"))]
pub mod backtrace;
pub mod condvar;
pub mod env;
pub mod ext;
pub mod fast_thread_local;
pub mod fd;
pub mod fs;
pub mod memchr;
pub mod mutex;
pub mod net;
pub mod os;
pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
pub mod rand;
pub mod rt;
pub mod rwlock;
pub mod stack_overflow;
pub mod stdio;
pub mod syscall;
pub mod thread;
pub mod thread_local;
pub mod time;

#[cfg(not(test))]
pub fn init() {
    use alloc::oom;

    oom::set_oom_handler(oom_handler);

    // A nicer handler for out-of-memory situations than the default one. This
    // one prints a message to stderr before aborting. It is critical that this
    // code does not allocate any memory since we are in an OOM situation. Any
    // errors are ignored while printing since there's nothing we can do about
    // them and we are about to exit anyways.
    fn oom_handler() -> ! {
        use intrinsics;
        let msg = "fatal runtime error: out of memory\n";
        unsafe {
            let _ = syscall::write(2, msg.as_bytes());
            intrinsics::abort();
        }
    }
}

pub fn decode_error_kind(errno: i32) -> ErrorKind {
    match errno {
        syscall::ECONNREFUSED => ErrorKind::ConnectionRefused,
        syscall::ECONNRESET => ErrorKind::ConnectionReset,
        syscall::EPERM | syscall::EACCES => ErrorKind::PermissionDenied,
        syscall::EPIPE => ErrorKind::BrokenPipe,
        syscall::ENOTCONN => ErrorKind::NotConnected,
        syscall::ECONNABORTED => ErrorKind::ConnectionAborted,
        syscall::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
        syscall::EADDRINUSE => ErrorKind::AddrInUse,
        syscall::ENOENT => ErrorKind::NotFound,
        syscall::EINTR => ErrorKind::Interrupted,
        syscall::EINVAL => ErrorKind::InvalidInput,
        syscall::ETIMEDOUT => ErrorKind::TimedOut,
        syscall::EEXIST => ErrorKind::AlreadyExists,

        // These two constants can have the same value on some systems,
        // but different values on others, so we can't use a match
        // clause
        x if x == syscall::EAGAIN || x == syscall::EWOULDBLOCK =>
            ErrorKind::WouldBlock,

        _ => ErrorKind::Other,
    }
}

pub fn cvt(result: Result<usize, syscall::Error>) -> io::Result<usize> {
    result.map_err(|err| io::Error::from_raw_os_error(err.errno))
}

/// On Redox, use an illegal instruction to abort
pub unsafe fn abort_internal() -> ! {
    ::core::intrinsics::abort();
}
<|endoftext|>


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

#[macro_use]
extern crate log;
extern crate libc;
extern crate errno;
extern crate threadpool;
extern crate simple_slab;

use std::io::Error;
use std::sync::Arc;
use std::cell::UnsafeCell;
use std::net::TcpListener;
use std::os::unix::io::{RawFd, AsRawFd};

use config::Config;

pub mod config;

mod server;

pub trait Stream : AsRawFd + Send + Sync {
    fn recv(&mut self) -> Result<Vec<Vec<u8>>, Error>;
    fn send(&mut self, buf: &[u8]) -> Result<(), Error>;
}

pub trait Handler {
    fn on_server_created(&mut self, fd: RawFd);
    fn on_new_connection(&mut self, fd: RawFd) -> Arc<UnsafeCell<Stream>>;
    fn on_data_received(&mut self, arc_stream: Arc<UnsafeCell<Stream>>, buf: Vec<u8>);
    fn on_connection_removed(&mut self, fd: RawFd);
}

pub fn begin<T>(handler: Box<T>, cfg: Config)
    where T: Handler + Send + Sync + 'static
{
    server::begin(handler, cfg);
}
<commit_msg>Set waiting before io to stop repeat reads<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

#[macro_use]
extern crate log;
extern crate libc;
extern crate errno;
extern crate threadpool;
extern crate simple_slab;

use std::io::Error;
use std::sync::Arc;
use std::cell::UnsafeCell;
use std::os::unix::io::{RawFd, AsRawFd};

use config::Config;

pub mod config;

mod server;

pub trait Stream : AsRawFd + Send + Sync {
    fn recv(&mut self) -> Result<Vec<Vec<u8>>, Error>;
    fn send(&mut self, buf: &[u8]) -> Result<(), Error>;
}

pub trait Handler {
    fn on_server_created(&mut self, fd: RawFd);
    fn on_new_connection(&mut self, fd: RawFd) -> Arc<UnsafeCell<Stream>>;
    fn on_data_received(&mut self, arc_stream: Arc<UnsafeCell<Stream>>, buf: Vec<u8>);
    fn on_connection_removed(&mut self, fd: RawFd);
}

pub fn begin<T>(handler: Box<T>, cfg: Config)
    where T: Handler + Send + Sync + 'static
{
    server::begin(handler, cfg);
}
<|endoftext|>


<commit_before>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UString {
    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

pub struct Iter<'a>(&'a [char]);

pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<commit_msg>Implement From<&UString> for String<commit_after>#![cfg_attr(test, deny(missing_docs, warnings))]
#![forbid(unused_variables)]

use std::{fmt, mem};
use std::borrow::{Borrow, ToOwned};
use std::default::Default;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo};

/// An owned sequence of Unicode scalar values, equivalent to `String`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UString(Vec<char>);

/// A Unicode string slice, equivalent to `str`.
pub struct UStr([char]);

impl UString {
    pub fn remove(&mut self, idx: usize) -> char {
        self.0.remove(idx)
    }
}

impl UStr {
    /// Returns the number of Unicode scalar values in this string.
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Retrieves the first character from a `&UStr` and returns it.
    ///
    /// This does not allocate a new string; instead, it returns a slice that points one character beyond the character that was shifted.
    ///
    /// If the slice does not contain any characters, None is returned instead.
    pub fn slice_shift_char(&self) -> Option<(char, &UStr)> {
        if self.len() == 0 {
            None
        } else {
            let ch = self[0];
            let next_s = &self[1..];
            Some((ch, next_s))
        }
    }
}

impl Borrow<UStr> for UString {
    fn borrow(&self) -> &UStr {
        &self
    }
}

impl Default for UString {
    fn default() -> UString {
        UString(Vec::new())
    }
}

impl Deref for UString {
    type Target = UStr;

    fn deref(&self) -> &UStr {
        unsafe {
            mem::transmute(&*self.0)
            // just so you can be clear what it is:
            //mem::transmute::<&[char], &UStr>(&*self.0)
        }
    }
}

impl From<String> for UString {
    fn from(string: String) -> UString {
        UString(string.chars().collect())
    }
}

impl From<Vec<char>> for UString {
    fn from(chars: Vec<char>) -> UString {
        UString(chars)
    }
}

impl<'a> From<&'a str> for UString {
    fn from(string: &'a str) -> UString {
        UString(string.chars().collect())
    }
}

impl<'a> From<&'a [char]> for UString {
    fn from(slice: &[char]) -> UString {
        UString(slice.to_vec())
    }
}

impl From<UString> for String {
    fn from(string: UString) -> String {
        String::from_iter(string)
    }
}

impl<'a> From<&'a UString> for String {
    fn from(string: &UString) -> String {
        String::from_iter(string.into_iter().cloned())
    }
}

impl<'a> From<&'a UStr> for String {
    fn from(slice: &UStr) -> String {
        String::from_iter(slice.into_iter().cloned())
    }
}

impl<C: Into<char>> FromIterator<C> for UString {
    fn from_iter<T>(iterator: T) -> UString where T: IntoIterator<Item=C> {
        UString(iterator.into_iter().map(C::into).collect())
    }
}

impl Hash for UString {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl Index<usize> for UStr {
    type Output = char;

    fn index(&self, idx: usize) -> &char {
        &self.0[idx]
    }
}

impl Index<Range<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: Range<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFrom<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeFrom<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl Index<RangeFull> for UStr {
    type Output = UStr;

    fn index(&self, _: RangeFull) -> &UStr {
        self
    }
}

impl Index<RangeTo<usize>> for UStr {
    type Output = UStr;

    fn index(&self, idx: RangeTo<usize>) -> &UStr {
        unsafe { mem::transmute(&self.0[idx]) }
    }
}

impl ToOwned for UStr {
    type Owned = UString;

    fn to_owned(&self) -> UString {
        UString::from(self.0.to_owned())
    }
}

impl fmt::Display for UStr {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for c in &self.0 {
            try!(write!(f, "{}", c));
        }
        Ok(())
    }
}

pub struct Iter<'a>(&'a [char]);

pub struct IntoIter(Vec<char>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a char;

    fn next(&mut self) -> Option<&'a char> {
        if self.0.len() > 0 {
            let result = &self.0[0];
            self.0 = &self.0[1..];
            Some(result)
        } else {
            None
        }
    }
}

impl Iterator for IntoIter {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.0.len() > 0 {
            Some(self.0.remove(0))
        } else {
            None
        }
    }
}

impl IntoIterator for UString {
    type Item = char;
    type IntoIter = IntoIter;

    fn into_iter(self) -> IntoIter {
        IntoIter(self.0)
    }
}

impl<'a> IntoIterator for &'a UString {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}

impl<'a> IntoIterator for &'a UStr {
    type Item = &'a char;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        Iter(&self.0)
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Benjamin Fry <benjaminfry@me.com>

use std::ascii::AsciiExt;

/// returns true if and only if the phrase is a palindrome
///
/// # Arguments
///
/// * `phrase` - the phrase to inspect
///
/// This is just to be fun with iterators...
/// This should be O(n/2), and would be fewer lines without all the comments.
pub fn is_palindrome(phrase: &str) -> bool {
    // get the chars iterator and associated index
    phrase.char_indices().filter(|&(_,c)| c.is_alphabetic())
                // zip with the second half...
                .zip(phrase.char_indices()
                           // which needs to be reversed...
                           .rev()
                           // and filter out bad cars
                           .filter(|&(_,c)| c.is_alphabetic()))
                // accept all input until the indexes have crossed
                .take_while(|&((first_count, _), (last_count, _))| {println!("{} < {}", first_count, last_count); first_count < last_count})
                // check that all the chars from the begining and end match
                .all(|((_, first_char), (_, last_char))| {
                    first_char.to_ascii_lowercase() == last_char.to_ascii_lowercase()
                })
}

/// this is a class array implementation (for comparison)
///
/// # Arguments
///
/// * `phrase` - the phrase to inspect
///
/// This is definitely not the most efficient, but is meant show the difference to above. And be
///  close to the semantics used in C/C++, with the exception of the chars().collect() this should
///  be O(n/2).
pub fn is_palindrome_classic(phrase: &str) -> bool {
    if phrase.len() == 0 { return true }

    // need to do this because Rust is rightly trying to force you away from treating strs as
    //  arrays
    let phrase: Vec<char> = phrase.chars().collect();

    // start from the beginning
    let mut first_idx = 0;

    // and the end, btw, don't forget the off-by-one b/c of the
    let mut last_idx = phrase.len() - 1;
    // loop and guard that we don't go too far
    while first_idx < last_idx {
        // filter out non-alphabetics
        if !phrase[first_idx].is_alphabetic() { first_idx += 1; continue }
        if !phrase[last_idx].is_alphabetic() { last_idx -= 1; continue }

        // compare the values
        if phrase[first_idx].to_ascii_lowercase() != phrase[last_idx].to_ascii_lowercase() {
            return false;
        }

        first_idx += 1;
        last_idx -= 1;
    }

    // is this actually simpler or more readable? I don't think so...

    true
}

#[test]
fn test_is_palindrome() {
    test_is_palindrome_base(is_palindrome);
}

#[test]
fn test_palindrome_classic() {
    test_is_palindrome_base(is_palindrome_classic);
}

#[cfg(test)]
fn test_is_palindrome_base<F>(is_palindrome: F) where F: Fn(&str) -> bool {
    assert!(is_palindrome(""));
    assert!(is_palindrome("a"));
    assert!(is_palindrome(".,,/.,/.,././.,=-=--"));
    assert!(is_palindrome("a,,,,,,,,,,,,,,,a"));
    assert!(is_palindrome("a,,,,,bb,,,,,,,,a"));
    assert!(is_palindrome("race car"));
    assert!(is_palindrome("racecar"));
    assert!(is_palindrome("raccar"));
    assert!(is_palindrome("A man, a plan, a canal, Panama!"));
    assert!(is_palindrome("Amor, Roma"));
    assert!(is_palindrome("stack cats"));
    assert!(is_palindrome("step on no pets"));
    assert!(is_palindrome("taco cat"));
    assert!(is_palindrome("put it up"));
    assert!(is_palindrome("Was it a car or a cat I saw?"));
    assert!(is_palindrome("No ‘x’ in Nixon"));

    // negative for good messure
    assert!(!is_palindrome("Not a palindrome"))
}
<commit_msg>removing unnecessary println<commit_after>// Copyright (C) 2016 Benjamin Fry <benjaminfry@me.com>

use std::ascii::AsciiExt;

/// returns true if and only if the phrase is a palindrome
///
/// # Arguments
///
/// * `phrase` - the phrase to inspect
///
/// This is just to be fun with iterators...
/// This should be O(n/2), and would be fewer lines without all the comments.
pub fn is_palindrome(phrase: &str) -> bool {
    // get the chars iterator and associated index
    phrase.char_indices().filter(|&(_,c)| c.is_alphabetic())
                // zip with the second half...
                .zip(phrase.char_indices()
                           // which needs to be reversed...
                           .rev()
                           // and filter out bad cars
                           .filter(|&(_,c)| c.is_alphabetic()))
                // accept all input until the indexes have crossed
                .take_while(|&((first_count, _), (last_count, _))| {first_count < last_count})
                // check that all the chars from the begining and end match
                .all(|((_, first_char), (_, last_char))| {
                    first_char.to_ascii_lowercase() == last_char.to_ascii_lowercase()
                })
}

/// this is a class array implementation (for comparison)
///
/// # Arguments
///
/// * `phrase` - the phrase to inspect
///
/// This is definitely not the most efficient, but is meant show the difference to above. And be
///  close to the semantics used in C/C++, with the exception of the chars().collect() this should
///  be O(n/2).
pub fn is_palindrome_classic(phrase: &str) -> bool {
    if phrase.len() == 0 { return true }

    // need to do this because Rust is rightly trying to force you away from treating strs as
    //  arrays
    let phrase: Vec<char> = phrase.chars().collect();

    // start from the beginning
    let mut first_idx = 0;

    // and the end, btw, don't forget the off-by-one b/c of the
    let mut last_idx = phrase.len() - 1;
    // loop and guard that we don't go too far
    while first_idx < last_idx {
        // filter out non-alphabetics
        if !phrase[first_idx].is_alphabetic() { first_idx += 1; continue }
        if !phrase[last_idx].is_alphabetic() { last_idx -= 1; continue }

        // compare the values
        if phrase[first_idx].to_ascii_lowercase() != phrase[last_idx].to_ascii_lowercase() {
            return false;
        }

        first_idx += 1;
        last_idx -= 1;
    }

    // is this actually simpler or more readable? I don't think so...

    true
}

#[test]
fn test_is_palindrome() {
    test_is_palindrome_base(is_palindrome);
}

#[test]
fn test_palindrome_classic() {
    test_is_palindrome_base(is_palindrome_classic);
}

#[cfg(test)]
fn test_is_palindrome_base<F>(is_palindrome: F) where F: Fn(&str) -> bool {
    assert!(is_palindrome(""));
    assert!(is_palindrome("a"));
    assert!(is_palindrome(".,,/.,/.,././.,=-=--"));
    assert!(is_palindrome("a,,,,,,,,,,,,,,,a"));
    assert!(is_palindrome("a,,,,,bb,,,,,,,,a"));
    assert!(is_palindrome("race car"));
    assert!(is_palindrome("racecar"));
    assert!(is_palindrome("raccar"));
    assert!(is_palindrome("A man, a plan, a canal, Panama!"));
    assert!(is_palindrome("Amor, Roma"));
    assert!(is_palindrome("stack cats"));
    assert!(is_palindrome("step on no pets"));
    assert!(is_palindrome("taco cat"));
    assert!(is_palindrome("put it up"));
    assert!(is_palindrome("Was it a car or a cat I saw?"));
    assert!(is_palindrome("No ‘x’ in Nixon"));

    // negative for good messure
    assert!(!is_palindrome("Not a palindrome"))
}
<|endoftext|>


<commit_before>//! Provides undo-redo functionality with dynamic dispatch and automatic command merging.
//!
//! It is an implementation of the command pattern, where all modifications are done
//! by creating objects of commands that applies the modifications. All commands knows
//! how to undo the changes it applies, and by using the provided data structures
//! it is easy to apply, undo, and redo changes made to a receiver.
//!
//! # Contents
//!
//! * [Record] provides stack based undo-redo functionality.
//! * [History] provides tree based undo-redo functionality that allows you to jump between different branches.
//! * [Queue] wraps a [Record] or [History] and extends them with queue functionality.
//! * [Checkpoint] wraps a [Record] or [History] and extends them with checkpoint functionality.
//! * Commands can be merged using the [merge!] macro or the [merge] method.
//!   When two commands are merged, undoing and redoing them are done in a single step.
//! * Configurable display formatting is provided when the `display` feature is enabled.
//! * Time stamps and time travel is provided when the `chrono` feature is enabled.
//!
//! # Examples
//!
//! Add this to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! undo = "0.31"
//! ```
//!
//! And this to `main.rs`:
//!
//! ```
//! use undo::{Command, Record};
//!
//! #[derive(Debug)]
//! struct Add(char);
//!
//! impl Command<String> for Add {
//!     fn apply(&mut self, s: &mut String) -> undo::Result {
//!         s.push(self.0);
//!         Ok(())
//!     }
//!
//!     fn undo(&mut self, s: &mut String) -> undo::Result {
//!         self.0 = s.pop().ok_or("`s` is empty")?;
//!         Ok(())
//!     }
//! }
//!
//! fn main() -> undo::Result {
//!     let mut record = Record::default();
//!     record.apply(Add('a'))?;
//!     record.apply(Add('b'))?;
//!     record.apply(Add('c'))?;
//!     assert_eq!(record.as_receiver(), "abc");
//!     record.undo().unwrap()?;
//!     record.undo().unwrap()?;
//!     record.undo().unwrap()?;
//!     assert_eq!(record.as_receiver(), "");
//!     record.redo().unwrap()?;
//!     record.redo().unwrap()?;
//!     record.redo().unwrap()?;
//!     assert_eq!(record.as_receiver(), "abc");
//!     Ok(())
//! }
//! ```
//!
//! [Record]: struct.Record.html
//! [History]: struct.History.html
//! [Queue]: struct.Queue.html
//! [Checkpoint]: struct.Checkpoint.html
//! [merge!]: macro.merge.html
//! [merge]: trait.Command.html#method.merge

#![doc(html_root_url = "https://docs.rs/undo/0.31.0")]
#![deny(
    bad_style,
    bare_trait_objects,
    missing_debug_implementations,
    missing_docs,
    unused_import_braces,
    unused_qualifications,
    unsafe_code,
    unstable_features
)]

mod checkpoint;
#[cfg(feature = "display")]
mod display;
mod history;
mod merge;
mod queue;
mod record;

#[cfg(feature = "chrono")]
use chrono::{DateTime, Utc};
use std::error::Error;
use std::fmt;

#[cfg(feature = "display")]
pub use self::display::Display;
pub use self::{
    checkpoint::Checkpoint,
    history::{History, HistoryBuilder},
    merge::Merged,
    queue::Queue,
    record::{Record, RecordBuilder},
};

/// A specialized Result type for undo-redo operations.
pub type Result = std::result::Result<(), Box<dyn Error + Send + Sync + 'static>>;

/// Base functionality for all commands.
#[cfg(not(feature = "display"))]
pub trait Command<R>: fmt::Debug + Send + Sync {
    /// Applies the command on the receiver and returns `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    fn apply(&mut self, receiver: &mut R) -> Result;

    /// Restores the state of the receiver as it was before the command was applied
    /// and returns `Ok` if everything went fine, and `Err` if something went wrong.
    fn undo(&mut self, receiver: &mut R) -> Result;

    /// Reapplies the command on the receiver and return `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    ///
    /// The default implementation uses the [`apply`] implementation.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.apply(receiver)
    }

    /// Used for automatic merging of commands.
    ///
    /// When commands are merged together, undoing and redoing them are done in one step.
    ///
    /// # Examples
    /// ```
    /// # use undo::{Command, Merge, Record};
    /// #[derive(Debug)]
    /// struct Add(char);
    ///
    /// impl Command<String> for Add {
    ///     fn apply(&mut self, s: &mut String) -> undo::Result {
    ///         s.push(self.0);
    ///         Ok(())
    ///     }
    ///
    ///     fn undo(&mut self, s: &mut String) -> undo::Result {
    ///         self.0 = s.pop().ok_or("`s` is empty")?;
    ///         Ok(())
    ///     }
    ///
    ///     fn merge(&self) -> Merge {
    ///         Merge::Always
    ///     }
    /// }
    ///
    /// fn main() -> undo::Result {
    ///     let mut record = Record::default();
    ///     // The `a`, `b`, and `c` commands are merged.
    ///     record.apply(Add('a'))?;
    ///     record.apply(Add('b'))?;
    ///     record.apply(Add('c'))?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     // Calling `undo` once will undo all merged commands.
    ///     record.undo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "");
    ///     // Calling `redo` once will redo all merged commands.
    ///     record.redo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     Ok(())
    /// }
    /// ```
    #[inline]
    fn merge(&self) -> Merge {
        Merge::Never
    }
}

/// Base functionality for all commands.
#[cfg(feature = "display")]
pub trait Command<R>: fmt::Debug + fmt::Display + Send + Sync {
    /// Applies the command on the receiver and returns `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    fn apply(&mut self, receiver: &mut R) -> Result;

    /// Restores the state of the receiver as it was before the command was applied
    /// and returns `Ok` if everything went fine, and `Err` if something went wrong.
    fn undo(&mut self, receiver: &mut R) -> Result;

    /// Reapplies the command on the receiver and return `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    ///
    /// The default implementation uses the [`apply`] implementation.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.apply(receiver)
    }

    /// Used for automatic merging of commands.
    ///
    /// When commands are merged together, undoing and redoing them are done in one step.
    ///
    /// # Examples
    /// ```
    /// # use undo::*;
    /// #[derive(Debug)]
    /// struct Add(char);
    ///
    /// impl Command<String> for Add {
    ///     fn apply(&mut self, s: &mut String) -> undo::Result {
    ///         s.push(self.0);
    ///         Ok(())
    ///     }
    ///
    ///     fn undo(&mut self, s: &mut String) -> undo::Result {
    ///         self.0 = s.pop().ok_or("`s` is empty")?;
    ///         Ok(())
    ///     }
    ///
    ///     fn merge(&self) -> Merge {
    ///         Merge::Always
    ///     }
    /// }
    ///
    /// fn main() -> undo::Result {
    ///     let mut record = Record::default();
    ///     // The `a`, `b`, and `c` commands are merged.
    ///     record.apply(Add('a'))?;
    ///     record.apply(Add('b'))?;
    ///     record.apply(Add('c'))?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     // Calling `undo` once will undo all merged commands.
    ///     record.undo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "");
    ///     // Calling `redo` once will redo all merged commands.
    ///     record.redo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     Ok(())
    /// }
    /// ```
    #[inline]
    fn merge(&self) -> Merge {
        Merge::Never
    }
}

impl<R, C: Command<R> + ?Sized> Command<R> for Box<C> {
    #[inline]
    fn apply(&mut self, receiver: &mut R) -> Result {
        (**self).apply(receiver)
    }

    #[inline]
    fn undo(&mut self, receiver: &mut R) -> Result {
        (**self).undo(receiver)
    }

    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        (**self).redo(receiver)
    }

    #[inline]
    fn merge(&self) -> Merge {
        (**self).merge()
    }
}

/// The signal sent when the record, the history, or the receiver changes.
///
/// When one of these states changes, they will send a corresponding signal to the user.
/// For example, if the record can no longer redo any commands, it sends a `Redo(false)`
/// signal to tell the user.
///
/// # Examples
/// ```
/// # use undo::{History, Signal};
/// # fn foo() -> History<String> {
/// let history = History::builder()
///     .connect(|signal| match signal {
///         Signal::Undo(on) => println!("undo: {}", on),
///         Signal::Redo(on) => println!("redo: {}", on),
///         Signal::Saved(on) => println!("saved: {}", on),
///         Signal::Current { old, new } => println!("current: {} -> {}", old, new),
///         Signal::Root { old, new } => println!("root: {} -> {}", old, new),
///     })
///     .default();
/// # history
/// # }
/// ```
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub enum Signal {
    /// Says if the record can undo.
    ///
    /// This signal will be emitted when the records ability to undo changes.
    Undo(bool),
    /// Says if the record can redo.
    ///
    /// This signal will be emitted when the records ability to redo changes.
    Redo(bool),
    /// Says if the receiver is in a saved state.
    ///
    /// This signal will be emitted when the record enters or leaves its receivers saved state.
    Saved(bool),
    /// Says if the current command has changed.
    ///
    /// This signal will be emitted when the current command has changed. This includes
    /// when two commands have been merged, in which case `old == new`.
    Current {
        /// The old current command.
        old: usize,
        /// The new current command.
        new: usize,
    },
    /// Says if the current branch, or root, has changed.
    ///
    /// This is only emitted from `History`.
    Root {
        /// The old root.
        old: usize,
        /// The new root.
        new: usize,
    },
}

/// Says if the command should merge with another command.
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub enum Merge {
    /// Always merges.
    Always,
    /// Merges if the two commands have the same value.
    If(u32),
    /// Never merges.
    Never,
}

/// A position in a history tree.
#[derive(Copy, Clone, Debug, Default, Hash, Ord, PartialOrd, Eq, PartialEq)]
struct At {
    branch: usize,
    current: usize,
}

struct Meta<R> {
    command: Box<dyn Command<R>>,
    #[cfg(feature = "chrono")]
    timestamp: DateTime<Utc>,
}

impl<R> Meta<R> {
    #[inline]
    fn new(command: impl Command<R> + 'static) -> Meta<R> {
        Meta {
            command: Box::new(command),
            #[cfg(feature = "chrono")]
            timestamp: Utc::now(),
        }
    }
}

impl<R> From<Box<dyn Command<R>>> for Meta<R> {
    #[inline]
    fn from(command: Box<dyn Command<R>>) -> Self {
        Meta {
            command,
            #[cfg(feature = "chrono")]
            timestamp: Utc::now(),
        }
    }
}

impl<R> Command<R> for Meta<R> {
    #[inline]
    fn apply(&mut self, receiver: &mut R) -> Result {
        self.command.apply(receiver)
    }

    #[inline]
    fn undo(&mut self, receiver: &mut R) -> Result {
        self.command.undo(receiver)
    }

    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.command.redo(receiver)
    }

    #[inline]
    fn merge(&self) -> Merge {
        self.command.merge()
    }
}

impl<R> fmt::Debug for Meta<R> {
    #[inline]
    #[cfg(not(feature = "chrono"))]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Meta")
            .field("command", &self.command)
            .finish()
    }

    #[inline]
    #[cfg(feature = "chrono")]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Meta")
            .field("command", &self.command)
            .field("timestamp", &self.timestamp)
            .finish()
    }
}

#[cfg(feature = "display")]
impl<R> fmt::Display for Meta<R> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        (&self.command as &dyn fmt::Display).fmt(f)
    }
}
<commit_msg>Use latest in html_root_url<commit_after>//! Provides undo-redo functionality with dynamic dispatch and automatic command merging.
//!
//! It is an implementation of the command pattern, where all modifications are done
//! by creating objects of commands that applies the modifications. All commands knows
//! how to undo the changes it applies, and by using the provided data structures
//! it is easy to apply, undo, and redo changes made to a receiver.
//!
//! # Contents
//!
//! * [Record] provides stack based undo-redo functionality.
//! * [History] provides tree based undo-redo functionality that allows you to jump between different branches.
//! * [Queue] wraps a [Record] or [History] and extends them with queue functionality.
//! * [Checkpoint] wraps a [Record] or [History] and extends them with checkpoint functionality.
//! * Commands can be merged using the [merge!] macro or the [merge] method.
//!   When two commands are merged, undoing and redoing them are done in a single step.
//! * Configurable display formatting is provided when the `display` feature is enabled.
//! * Time stamps and time travel is provided when the `chrono` feature is enabled.
//!
//! # Examples
//!
//! Add this to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! undo = "0.31"
//! ```
//!
//! And this to `main.rs`:
//!
//! ```
//! use undo::{Command, Record};
//!
//! #[derive(Debug)]
//! struct Add(char);
//!
//! impl Command<String> for Add {
//!     fn apply(&mut self, s: &mut String) -> undo::Result {
//!         s.push(self.0);
//!         Ok(())
//!     }
//!
//!     fn undo(&mut self, s: &mut String) -> undo::Result {
//!         self.0 = s.pop().ok_or("`s` is empty")?;
//!         Ok(())
//!     }
//! }
//!
//! fn main() -> undo::Result {
//!     let mut record = Record::default();
//!     record.apply(Add('a'))?;
//!     record.apply(Add('b'))?;
//!     record.apply(Add('c'))?;
//!     assert_eq!(record.as_receiver(), "abc");
//!     record.undo().unwrap()?;
//!     record.undo().unwrap()?;
//!     record.undo().unwrap()?;
//!     assert_eq!(record.as_receiver(), "");
//!     record.redo().unwrap()?;
//!     record.redo().unwrap()?;
//!     record.redo().unwrap()?;
//!     assert_eq!(record.as_receiver(), "abc");
//!     Ok(())
//! }
//! ```
//!
//! [Record]: struct.Record.html
//! [History]: struct.History.html
//! [Queue]: struct.Queue.html
//! [Checkpoint]: struct.Checkpoint.html
//! [merge!]: macro.merge.html
//! [merge]: trait.Command.html#method.merge

#![doc(html_root_url = "https://docs.rs/undo/latest")]
#![deny(
    bad_style,
    bare_trait_objects,
    missing_debug_implementations,
    missing_docs,
    unused_import_braces,
    unused_qualifications,
    unsafe_code,
    unstable_features
)]

mod checkpoint;
#[cfg(feature = "display")]
mod display;
mod history;
mod merge;
mod queue;
mod record;

#[cfg(feature = "chrono")]
use chrono::{DateTime, Utc};
use std::error::Error;
use std::fmt;

#[cfg(feature = "display")]
pub use self::display::Display;
pub use self::{
    checkpoint::Checkpoint,
    history::{History, HistoryBuilder},
    merge::Merged,
    queue::Queue,
    record::{Record, RecordBuilder},
};

/// A specialized Result type for undo-redo operations.
pub type Result = std::result::Result<(), Box<dyn Error + Send + Sync + 'static>>;

/// Base functionality for all commands.
#[cfg(not(feature = "display"))]
pub trait Command<R>: fmt::Debug + Send + Sync {
    /// Applies the command on the receiver and returns `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    fn apply(&mut self, receiver: &mut R) -> Result;

    /// Restores the state of the receiver as it was before the command was applied
    /// and returns `Ok` if everything went fine, and `Err` if something went wrong.
    fn undo(&mut self, receiver: &mut R) -> Result;

    /// Reapplies the command on the receiver and return `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    ///
    /// The default implementation uses the [`apply`] implementation.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.apply(receiver)
    }

    /// Used for automatic merging of commands.
    ///
    /// When commands are merged together, undoing and redoing them are done in one step.
    ///
    /// # Examples
    /// ```
    /// # use undo::{Command, Merge, Record};
    /// #[derive(Debug)]
    /// struct Add(char);
    ///
    /// impl Command<String> for Add {
    ///     fn apply(&mut self, s: &mut String) -> undo::Result {
    ///         s.push(self.0);
    ///         Ok(())
    ///     }
    ///
    ///     fn undo(&mut self, s: &mut String) -> undo::Result {
    ///         self.0 = s.pop().ok_or("`s` is empty")?;
    ///         Ok(())
    ///     }
    ///
    ///     fn merge(&self) -> Merge {
    ///         Merge::Always
    ///     }
    /// }
    ///
    /// fn main() -> undo::Result {
    ///     let mut record = Record::default();
    ///     // The `a`, `b`, and `c` commands are merged.
    ///     record.apply(Add('a'))?;
    ///     record.apply(Add('b'))?;
    ///     record.apply(Add('c'))?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     // Calling `undo` once will undo all merged commands.
    ///     record.undo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "");
    ///     // Calling `redo` once will redo all merged commands.
    ///     record.redo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     Ok(())
    /// }
    /// ```
    #[inline]
    fn merge(&self) -> Merge {
        Merge::Never
    }
}

/// Base functionality for all commands.
#[cfg(feature = "display")]
pub trait Command<R>: fmt::Debug + fmt::Display + Send + Sync {
    /// Applies the command on the receiver and returns `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    fn apply(&mut self, receiver: &mut R) -> Result;

    /// Restores the state of the receiver as it was before the command was applied
    /// and returns `Ok` if everything went fine, and `Err` if something went wrong.
    fn undo(&mut self, receiver: &mut R) -> Result;

    /// Reapplies the command on the receiver and return `Ok` if everything went fine,
    /// and `Err` if something went wrong.
    ///
    /// The default implementation uses the [`apply`] implementation.
    ///
    /// [`apply`]: trait.Command.html#tymethod.apply
    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.apply(receiver)
    }

    /// Used for automatic merging of commands.
    ///
    /// When commands are merged together, undoing and redoing them are done in one step.
    ///
    /// # Examples
    /// ```
    /// # use undo::*;
    /// #[derive(Debug)]
    /// struct Add(char);
    ///
    /// impl Command<String> for Add {
    ///     fn apply(&mut self, s: &mut String) -> undo::Result {
    ///         s.push(self.0);
    ///         Ok(())
    ///     }
    ///
    ///     fn undo(&mut self, s: &mut String) -> undo::Result {
    ///         self.0 = s.pop().ok_or("`s` is empty")?;
    ///         Ok(())
    ///     }
    ///
    ///     fn merge(&self) -> Merge {
    ///         Merge::Always
    ///     }
    /// }
    ///
    /// fn main() -> undo::Result {
    ///     let mut record = Record::default();
    ///     // The `a`, `b`, and `c` commands are merged.
    ///     record.apply(Add('a'))?;
    ///     record.apply(Add('b'))?;
    ///     record.apply(Add('c'))?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     // Calling `undo` once will undo all merged commands.
    ///     record.undo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "");
    ///     // Calling `redo` once will redo all merged commands.
    ///     record.redo().unwrap()?;
    ///     assert_eq!(record.as_receiver(), "abc");
    ///     Ok(())
    /// }
    /// ```
    #[inline]
    fn merge(&self) -> Merge {
        Merge::Never
    }
}

impl<R, C: Command<R> + ?Sized> Command<R> for Box<C> {
    #[inline]
    fn apply(&mut self, receiver: &mut R) -> Result {
        (**self).apply(receiver)
    }

    #[inline]
    fn undo(&mut self, receiver: &mut R) -> Result {
        (**self).undo(receiver)
    }

    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        (**self).redo(receiver)
    }

    #[inline]
    fn merge(&self) -> Merge {
        (**self).merge()
    }
}

/// The signal sent when the record, the history, or the receiver changes.
///
/// When one of these states changes, they will send a corresponding signal to the user.
/// For example, if the record can no longer redo any commands, it sends a `Redo(false)`
/// signal to tell the user.
///
/// # Examples
/// ```
/// # use undo::{History, Signal};
/// # fn foo() -> History<String> {
/// let history = History::builder()
///     .connect(|signal| match signal {
///         Signal::Undo(on) => println!("undo: {}", on),
///         Signal::Redo(on) => println!("redo: {}", on),
///         Signal::Saved(on) => println!("saved: {}", on),
///         Signal::Current { old, new } => println!("current: {} -> {}", old, new),
///         Signal::Root { old, new } => println!("root: {} -> {}", old, new),
///     })
///     .default();
/// # history
/// # }
/// ```
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub enum Signal {
    /// Says if the record can undo.
    ///
    /// This signal will be emitted when the records ability to undo changes.
    Undo(bool),
    /// Says if the record can redo.
    ///
    /// This signal will be emitted when the records ability to redo changes.
    Redo(bool),
    /// Says if the receiver is in a saved state.
    ///
    /// This signal will be emitted when the record enters or leaves its receivers saved state.
    Saved(bool),
    /// Says if the current command has changed.
    ///
    /// This signal will be emitted when the current command has changed. This includes
    /// when two commands have been merged, in which case `old == new`.
    Current {
        /// The old current command.
        old: usize,
        /// The new current command.
        new: usize,
    },
    /// Says if the current branch, or root, has changed.
    ///
    /// This is only emitted from `History`.
    Root {
        /// The old root.
        old: usize,
        /// The new root.
        new: usize,
    },
}

/// Says if the command should merge with another command.
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub enum Merge {
    /// Always merges.
    Always,
    /// Merges if the two commands have the same value.
    If(u32),
    /// Never merges.
    Never,
}

/// A position in a history tree.
#[derive(Copy, Clone, Debug, Default, Hash, Ord, PartialOrd, Eq, PartialEq)]
struct At {
    branch: usize,
    current: usize,
}

struct Meta<R> {
    command: Box<dyn Command<R>>,
    #[cfg(feature = "chrono")]
    timestamp: DateTime<Utc>,
}

impl<R> Meta<R> {
    #[inline]
    fn new(command: impl Command<R> + 'static) -> Meta<R> {
        Meta {
            command: Box::new(command),
            #[cfg(feature = "chrono")]
            timestamp: Utc::now(),
        }
    }
}

impl<R> From<Box<dyn Command<R>>> for Meta<R> {
    #[inline]
    fn from(command: Box<dyn Command<R>>) -> Self {
        Meta {
            command,
            #[cfg(feature = "chrono")]
            timestamp: Utc::now(),
        }
    }
}

impl<R> Command<R> for Meta<R> {
    #[inline]
    fn apply(&mut self, receiver: &mut R) -> Result {
        self.command.apply(receiver)
    }

    #[inline]
    fn undo(&mut self, receiver: &mut R) -> Result {
        self.command.undo(receiver)
    }

    #[inline]
    fn redo(&mut self, receiver: &mut R) -> Result {
        self.command.redo(receiver)
    }

    #[inline]
    fn merge(&self) -> Merge {
        self.command.merge()
    }
}

impl<R> fmt::Debug for Meta<R> {
    #[inline]
    #[cfg(not(feature = "chrono"))]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Meta")
            .field("command", &self.command)
            .finish()
    }

    #[inline]
    #[cfg(feature = "chrono")]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Meta")
            .field("command", &self.command)
            .field("timestamp", &self.timestamp)
            .finish()
    }
}

#[cfg(feature = "display")]
impl<R> fmt::Display for Meta<R> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        (&self.command as &dyn fmt::Display).fmt(f)
    }
}
<|endoftext|>


<commit_before>//! This crate only provides the `MaybeOwned` enum
//!
//! Take a look at it's documentation for more information.
//!
#![warn(missing_docs)]
use std::ops::Deref;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::fmt;

use self::MaybeOwned::*;

/// This type provides a way to store data to which you either have a
/// reference to or which you do own.
///
/// It provides `From<T>`, `From<&'a T>` implementations and, in difference
/// to `Cow` does _not_ require `ToOwned` to be implemented which makes it
/// compatible with non cloneable data, as a draw back of this it does not
/// know about `ToOwned`. As a consequence of it can't know that `&str` should
/// be the borrowed version of `String` and not `&String` this is especially
/// bad wrt. `Box` as the borrowed version of `Box<T>` would be `&Box<T>`.
///
/// While this crate has some drawbacks compared to `Cow` is has the benefit,
/// that it works with Types which neither implement `Clone` nor `ToOwned`.
/// Another benefit lies in the ability to write API functions which accept
/// a generic parameter `E: Into<MaybeOwned<'a, T>>` as the API consumer can
/// pass `T`, `&'a T` and `MaybeOwned<'a, T>` as argument, without requiring
/// a explicit `Cow::Onwed` or a split into two functions one accepting
/// owed and the other borrowed values.
///
/// # Alternatives
///
/// If you mainly have values implementing `ToOwned` like `&str`/`String`, `Path`/`PathBuf` or
/// `&[T]`/`Vec<T>` using `std::borrow::Cow` might be preferable.
///
/// If you want to be able to treat `&T`, `&mut T`, `Box<T>` and `Arc<T>` the same
/// consider using [`reffers::rbma::RBMA`](https://docs.rs/reffers)
/// (through not all types/platforms are supported because
/// as it relies on the fact that for many pointers the lowest two bits are 0, and stores
/// the discriminant in them, nevertheless this is can only be used with 32bit-aligned data,
/// e.g. using a &u8 _might_ fail). RBMA also allows you to recover a `&mut T` if it was created
/// from `Box<T>`, `&mut T` or a unique `Arc`.
///
///
/// # Examples
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// struct PseudoBigData(u8);
/// fn pseudo_register_fn<'a, E>(_val: E) where E: Into<MaybeOwned<'a, PseudoBigData>> { }
///
/// let data = PseudoBigData(12);
/// let data2 = PseudoBigData(13);
///
/// pseudo_register_fn(&data);
/// pseudo_register_fn(&data);
/// pseudo_register_fn(data2);
/// pseudo_register_fn(MaybeOwned::Owned(PseudoBigData(111)));
/// ```
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// #[repr(C)]
/// struct OpaqueFFI {
///     ref1:  * const u8
///     //we also might want to have PhantomData etc.
/// }
///
/// // does not work as it does not implement `ToOwned`
/// // let _ = Cow::Owned(OpaqueFFI { ref1: 0 as *const u8});
///
/// // ok, MaybeOwned can do this (but can't do &str<->String as tread of)
/// let _ = MaybeOwned::Owned(OpaqueFFI { ref1: 0 as *const u8 });
/// ```
#[derive(Debug)]
pub enum MaybeOwned<'a, T: 'a> {
    /// owns T
    Owned(T),
    /// has a reference to T
    Borrowed(&'a T)
}

impl<'a, T> MaybeOwned<'a, T> {

    /// returns true if the data is owned else false
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            Borrowed(_) => false
        }
    }
}

impl<'a, T> Deref for MaybeOwned<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        match *self {
            Owned(ref v) => v,
            Borrowed(v) => v
        }
    }
}

impl<'a, T> From<&'a T> for MaybeOwned<'a, T> {
    fn from(v: &'a T) -> MaybeOwned<'a, T> {
        Borrowed(v)
    }
}

impl<'a, T> From<T> for MaybeOwned<'a, T> {
    fn from(v: T) -> MaybeOwned<'a, T> {
        Owned(v)
    }
}

impl<'a, T> Default for MaybeOwned<'a, T> where T: Default {
    fn default() -> Self {
        Owned(T::default())
    }
}

impl<'a, T> Clone for MaybeOwned<'a, T> where T: Clone {
    fn clone(&self) -> MaybeOwned<'a, T> {
        match *self {
            Owned(ref v) => Owned(v.clone()),
            Borrowed(v) => Borrowed(v)
        }
    }
}

impl<'a, 'b, A, B> PartialEq<MaybeOwned<'b, B>> for MaybeOwned<'a, A>
    where A: PartialEq<B>
{
    #[inline]
    fn eq(&self, other: &MaybeOwned<'b, B>) -> bool {
        PartialEq::eq(self.deref(), other.deref())
    }
}

impl<'a, T> Eq for MaybeOwned<'a, T> where T: Eq {}

impl<'a, T> PartialOrd for MaybeOwned<'a, T>
    where T: PartialOrd
{
    #[inline]
    fn partial_cmp(&self, other: &MaybeOwned<'a, T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Ord for MaybeOwned<'a, T>
    where T: Ord
{
    #[inline]
    fn cmp(&self, other: &MaybeOwned<'a, T>) -> Ordering {
        Ord::cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Hash for MaybeOwned<'a, T>
    where T: Hash
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(self.deref(), state)
    }
}

impl<'a, T> fmt::Display for MaybeOwned<'a, T>
    where T: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Owned(ref o) => fmt::Display::fmt(o, f),
            Borrowed(b) => fmt::Display::fmt(b, f),
        }
    }
}

impl<'a, T> MaybeOwned<'a, T> where T: Clone {

    /// Aquires a mutable reference to owned data.
    ///
    /// Clones data if it is not already owned.
    ///
    /// ## Example
    ///
    /// ```
    /// use maybe_owned::MaybeOwned;
    ///
    /// #[derive(Clone, Debug, PartialEq, Eq)]
    /// struct PseudoBigData(u8);
    ///
    /// let data = PseudoBigData(12);
    ///
    /// let mut maybe: MaybeOwned<PseudoBigData> = (&data).into();
    /// assert_eq!(false, maybe.is_owned());
    ///
    /// {
    ///     let reference = maybe.to_mut();
    ///     assert_eq!(&mut PseudoBigData(12), reference);
    /// }
    /// assert!(maybe.is_owned());
    /// ```
    ///
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Owned(ref mut v) => v,
            Borrowed(v) => {
                *self = Owned(v.clone());
                match *self {
                    Owned(ref mut v) => v,
                    Borrowed(..) => unreachable!()
                }
            }

        }
    }

    /// Extracts the owned data.
    ///
    /// If the data is borrowed it is cloned before being extracted.
    pub fn into_owned(self) -> T {
        match self {
            Owned(v) => v,
            Borrowed(v) => v.clone()
        }
    }
}

#[cfg(test)]
mod tests {
    use super::MaybeOwned;

    type TestType = Vec<()>;

    fn with_into<'a, I: Into<MaybeOwned<'a, TestType>>>(v: I) -> MaybeOwned<'a, TestType> {
        v.into()
    }

    #[test]
    fn is_owned() {
        let data = TestType::default();
        assert!(MaybeOwned::Owned(data).is_owned());
    }

    #[test]
    fn into_with_owned() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(with_into(data).is_owned())

    }
    #[test]
    fn into_with_borrow() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(!with_into(&data).is_owned());
    }

    #[test]
    fn clone_owned() {
        let maybe = MaybeOwned::<TestType>::default();
        assert!(maybe.clone().is_owned());
    }

    #[test]
    fn clone_borrow() {
        let data = TestType::default();
        let maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.clone().is_owned());
    }

    #[test]
    fn to_mut() {
        let data = TestType::default();
        let mut maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.is_owned());
        {
            let _mut_ref = maybe.to_mut();
        }
        assert!(maybe.is_owned());
    }

    #[test]
    fn into_inner() {
        let data = vec![1u32,2];
        let maybe: MaybeOwned<Vec<u32>> = (&data).into();
        assert_eq!(data, maybe.into_owned());
    }

    #[test]
    fn has_default() {
        #[derive(Default)]
        struct TestType(u8);
        let _x: MaybeOwned<TestType> = Default::default();
    }

    #[test]
    fn has_clone() {
        #[derive(Clone)]
        struct TestType(u8);
        let _x  = TestType(12).clone();
    }

    #[test]
    fn has_partial_eq() {
        #[derive(PartialEq)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_eq() {
        #[derive(PartialEq, Eq)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_partial_ord() {
        #[derive(PartialEq, PartialOrd)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_ord() {
        #[derive(PartialEq, Eq, PartialOrd, Ord)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_hash() {
        use std::collections::HashMap;

        let mut map = HashMap::new();
        map.insert(MaybeOwned::Owned(42), 33);

        assert_eq!(map.get(&MaybeOwned::Borrowed(&42)), Some(&33));
    }

    #[test]
    fn has_display() {
        let n = 33;
        let a = MaybeOwned::Owned(42);
        let b = MaybeOwned::Borrowed(&n);

        let s = format!("{} {}", a, b);

        assert_eq!(s, "42 33");
    }
}
<commit_msg>added conversion From/Into std::borrow::Cow<commit_after>//! This crate only provides the `MaybeOwned` enum
//!
//! Take a look at it's documentation for more information.
//!
#![warn(missing_docs)]
use std::ops::Deref;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::fmt;
use std::borrow::Cow;

use self::MaybeOwned::*;

/// This type provides a way to store data to which you either have a
/// reference to or which you do own.
///
/// It provides `From<T>`, `From<&'a T>` implementations and, in difference
/// to `Cow` does _not_ require `ToOwned` to be implemented which makes it
/// compatible with non cloneable data, as a draw back of this it does not
/// know about `ToOwned`. As a consequence of it can't know that `&str` should
/// be the borrowed version of `String` and not `&String` this is especially
/// bad wrt. `Box` as the borrowed version of `Box<T>` would be `&Box<T>`.
///
/// While this crate has some drawbacks compared to `Cow` is has the benefit,
/// that it works with Types which neither implement `Clone` nor `ToOwned`.
/// Another benefit lies in the ability to write API functions which accept
/// a generic parameter `E: Into<MaybeOwned<'a, T>>` as the API consumer can
/// pass `T`, `&'a T` and `MaybeOwned<'a, T>` as argument, without requiring
/// a explicit `Cow::Onwed` or a split into two functions one accepting
/// owed and the other borrowed values.
///
/// # Alternatives
///
/// If you mainly have values implementing `ToOwned` like `&str`/`String`, `Path`/`PathBuf` or
/// `&[T]`/`Vec<T>` using `std::borrow::Cow` might be preferable.
///
/// If you want to be able to treat `&T`, `&mut T`, `Box<T>` and `Arc<T>` the same
/// consider using [`reffers::rbma::RBMA`](https://docs.rs/reffers)
/// (through not all types/platforms are supported because
/// as it relies on the fact that for many pointers the lowest two bits are 0, and stores
/// the discriminant in them, nevertheless this is can only be used with 32bit-aligned data,
/// e.g. using a &u8 _might_ fail). RBMA also allows you to recover a `&mut T` if it was created
/// from `Box<T>`, `&mut T` or a unique `Arc`.
///
///
/// # Examples
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// struct PseudoBigData(u8);
/// fn pseudo_register_fn<'a, E>(_val: E) where E: Into<MaybeOwned<'a, PseudoBigData>> { }
///
/// let data = PseudoBigData(12);
/// let data2 = PseudoBigData(13);
///
/// pseudo_register_fn(&data);
/// pseudo_register_fn(&data);
/// pseudo_register_fn(data2);
/// pseudo_register_fn(MaybeOwned::Owned(PseudoBigData(111)));
/// ```
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// #[repr(C)]
/// struct OpaqueFFI {
///     ref1:  * const u8
///     //we also might want to have PhantomData etc.
/// }
///
/// // does not work as it does not implement `ToOwned`
/// // let _ = Cow::Owned(OpaqueFFI { ref1: 0 as *const u8});
///
/// // ok, MaybeOwned can do this (but can't do &str<->String as tread of)
/// let _ = MaybeOwned::Owned(OpaqueFFI { ref1: 0 as *const u8 });
/// ```
#[derive(Debug)]
pub enum MaybeOwned<'a, T: 'a> {
    /// owns T
    Owned(T),
    /// has a reference to T
    Borrowed(&'a T)
}

impl<'a, T> MaybeOwned<'a, T> {

    /// returns true if the data is owned else false
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            Borrowed(_) => false
        }
    }
}

impl<'a, T> Deref for MaybeOwned<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        match *self {
            Owned(ref v) => v,
            Borrowed(v) => v
        }
    }
}

impl<'a, T> From<&'a T> for MaybeOwned<'a, T> {
    fn from(v: &'a T) -> MaybeOwned<'a, T> {
        Borrowed(v)
    }
}

impl<'a, T> From<T> for MaybeOwned<'a, T> {
    fn from(v: T) -> MaybeOwned<'a, T> {
        Owned(v)
    }
}

impl<'a, T> From<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn from(cow: Cow<'a, T>) -> MaybeOwned<'a, T> {
        match cow {
            Cow::Owned(v) => MaybeOwned::Owned(v),
            Cow::Borrowed(v) => MaybeOwned::Borrowed(v),
        }
    }
}

impl<'a, T> Into<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn into(self) -> Cow<'a, T> {
        match self {
            MaybeOwned::Owned(v) => Cow::Owned(v),
            MaybeOwned::Borrowed(v) => Cow::Borrowed(v),
        }
    }
}

impl<'a, T> Default for MaybeOwned<'a, T> where T: Default {
    fn default() -> Self {
        Owned(T::default())
    }
}

impl<'a, T> Clone for MaybeOwned<'a, T> where T: Clone {
    fn clone(&self) -> MaybeOwned<'a, T> {
        match *self {
            Owned(ref v) => Owned(v.clone()),
            Borrowed(v) => Borrowed(v)
        }
    }
}

impl<'a, 'b, A, B> PartialEq<MaybeOwned<'b, B>> for MaybeOwned<'a, A>
    where A: PartialEq<B>
{
    #[inline]
    fn eq(&self, other: &MaybeOwned<'b, B>) -> bool {
        PartialEq::eq(self.deref(), other.deref())
    }
}

impl<'a, T> Eq for MaybeOwned<'a, T> where T: Eq {}

impl<'a, T> PartialOrd for MaybeOwned<'a, T>
    where T: PartialOrd
{
    #[inline]
    fn partial_cmp(&self, other: &MaybeOwned<'a, T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Ord for MaybeOwned<'a, T>
    where T: Ord
{
    #[inline]
    fn cmp(&self, other: &MaybeOwned<'a, T>) -> Ordering {
        Ord::cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Hash for MaybeOwned<'a, T>
    where T: Hash
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(self.deref(), state)
    }
}

impl<'a, T> fmt::Display for MaybeOwned<'a, T>
    where T: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Owned(ref o) => fmt::Display::fmt(o, f),
            Borrowed(b) => fmt::Display::fmt(b, f),
        }
    }
}

impl<'a, T> MaybeOwned<'a, T> where T: Clone {

    /// Aquires a mutable reference to owned data.
    ///
    /// Clones data if it is not already owned.
    ///
    /// ## Example
    ///
    /// ```
    /// use maybe_owned::MaybeOwned;
    ///
    /// #[derive(Clone, Debug, PartialEq, Eq)]
    /// struct PseudoBigData(u8);
    ///
    /// let data = PseudoBigData(12);
    ///
    /// let mut maybe: MaybeOwned<PseudoBigData> = (&data).into();
    /// assert_eq!(false, maybe.is_owned());
    ///
    /// {
    ///     let reference = maybe.to_mut();
    ///     assert_eq!(&mut PseudoBigData(12), reference);
    /// }
    /// assert!(maybe.is_owned());
    /// ```
    ///
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Owned(ref mut v) => v,
            Borrowed(v) => {
                *self = Owned(v.clone());
                match *self {
                    Owned(ref mut v) => v,
                    Borrowed(..) => unreachable!()
                }
            }

        }
    }

    /// Extracts the owned data.
    ///
    /// If the data is borrowed it is cloned before being extracted.
    pub fn into_owned(self) -> T {
        match self {
            Owned(v) => v,
            Borrowed(v) => v.clone()
        }
    }
}

#[cfg(test)]
mod tests {
    use super::MaybeOwned;

    type TestType = Vec<()>;

    fn with_into<'a, I: Into<MaybeOwned<'a, TestType>>>(v: I) -> MaybeOwned<'a, TestType> {
        v.into()
    }

    #[test]
    fn is_owned() {
        let data = TestType::default();
        assert!(MaybeOwned::Owned(data).is_owned());
    }

    #[test]
    fn into_with_owned() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(with_into(data).is_owned())

    }
    #[test]
    fn into_with_borrow() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(!with_into(&data).is_owned());
    }

    #[test]
    fn clone_owned() {
        let maybe = MaybeOwned::<TestType>::default();
        assert!(maybe.clone().is_owned());
    }

    #[test]
    fn clone_borrow() {
        let data = TestType::default();
        let maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.clone().is_owned());
    }

    #[test]
    fn to_mut() {
        let data = TestType::default();
        let mut maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.is_owned());
        {
            let _mut_ref = maybe.to_mut();
        }
        assert!(maybe.is_owned());
    }

    #[test]
    fn into_inner() {
        let data = vec![1u32,2];
        let maybe: MaybeOwned<Vec<u32>> = (&data).into();
        assert_eq!(data, maybe.into_owned());
    }

    #[test]
    fn has_default() {
        #[derive(Default)]
        struct TestType(u8);
        let _x: MaybeOwned<TestType> = Default::default();
    }

    #[test]
    fn has_clone() {
        #[derive(Clone)]
        struct TestType(u8);
        let _x  = TestType(12).clone();
    }

    #[test]
    fn has_partial_eq() {
        #[derive(PartialEq)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_eq() {
        #[derive(PartialEq, Eq)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_partial_ord() {
        #[derive(PartialEq, PartialOrd)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_ord() {
        #[derive(PartialEq, Eq, PartialOrd, Ord)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_hash() {
        use std::collections::HashMap;

        let mut map = HashMap::new();
        map.insert(MaybeOwned::Owned(42), 33);

        assert_eq!(map.get(&MaybeOwned::Borrowed(&42)), Some(&33));
    }

    #[test]
    fn has_display() {
        let n = 33;
        let a = MaybeOwned::Owned(42);
        let b = MaybeOwned::Borrowed(&n);

        let s = format!("{} {}", a, b);

        assert_eq!(s, "42 33");
    }

    #[test]
    fn from_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<MaybeOwned<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(Cow::Owned(42), 42);
        test(Cow::Borrowed(&n), n);
    }

    #[test]
    fn into_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<Cow<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(MaybeOwned::Owned(42), 42);
        test(MaybeOwned::Borrowed(&n), n);
    }
}
<|endoftext|>