<commit_before>use crate::cmp::Ordering;
use crate::time::Duration;

use core::hash::{Hash, Hasher};

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
use crate::convert::TryInto;

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    const fn zero() -> Timespec {
        Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
    }

    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
            // to optimize it into a branchless form (see also #75545):
            //
            // 1. `self.t.tv_sec - other.t.tv_sec` shows up as a common expression
            //    in both branches, i.e. the `else` must have its `- 1`
            //    subtraction after the common one, not interleaved with it
            //    (it used to be `self.t.tv_sec - 1 - other.t.tv_sec`)
            //
            // 2. the `Duration::new` call (or any other additional complexity)
            //    is outside of the `if`-`else`, not duplicated in both branches
            //
            // Ideally this code could be rearranged such that it more
            // directly expresses the lower-cost behavior we want from it.
            let (secs, nsec) = if self.t.tv_nsec >= other.t.tv_nsec {
                ((self.t.tv_sec - other.t.tv_sec) as u64, (self.t.tv_nsec - other.t.tv_nsec) as u32)
            } else {
                (
                    (self.t.tv_sec - other.t.tv_sec - 1) as u64,
                    self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
                )
            };

            Ok(Duration::new(secs, nsec))
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }

    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

impl Hash for Timespec {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.t.tv_sec.hash(state);
        self.t.tv_nsec.hash(state);
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use crate::fmt;
    use crate::sync::atomic::{AtomicBool, AtomicU64, Ordering};
    use crate::sys::cvt;
    use crate::sys_common::mul_div_u64;
    use crate::time::Duration;

    use super::Timespec;
    use super::NSEC_PER_SEC;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
    pub struct Instant {
        t: u64,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    #[repr(C)]
    #[derive(Copy, Clone)]
    struct mach_timebase_info {
        numer: u32,
        denom: u32,
    }
    type mach_timebase_info_t = *mut mach_timebase_info;
    type kern_return_t = libc::c_int;

    impl Instant {
        pub fn now() -> Instant {
            extern "C" {
                fn mach_absolute_time() -> u64;
            }
            Instant { t: unsafe { mach_absolute_time() } }
        }

        pub const fn zero() -> Instant {
            Instant { t: 0 }
        }

        pub fn actually_monotonic() -> bool {
            true
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            let diff = self.t.checked_sub(other.t)?;
            let info = info();
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32))
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use crate::ptr;

            let mut s = libc::timeval { tv_sec: 0, tv_usec: 0 };
            cvt(unsafe { libc::gettimeofday(&mut s, ptr::null_mut()) }).unwrap();
            return SystemTime::from(s);
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
        let nanos =
            dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as u64)?;
        let info = info();
        Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
    }

    fn info() -> mach_timebase_info {
        static INITIALIZED: AtomicBool = AtomicBool::new(false);
        static INFO_BITS: AtomicU64 = AtomicU64::new(0);

        // If a previous thread has initialized `INFO_BITS`, use that.
        if INITIALIZED.load(Ordering::Acquire) {
            // Note: `Relaxed` is correct here and below -- the `Acquire` /
            // `Release` pair used for `INITIALIZED` ensures this load can see
            // the corresponding store below.
            return info_from_bits(INFO_BITS.load(Ordering::Relaxed));
        }

        // ... otherwise learn for ourselves ...
        extern "C" {
            fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t;
        }

        let mut info = info_from_bits(0);
        unsafe {
            mach_timebase_info(&mut info);
        }

        // This is racy, but the race should be against other threads trying to
        // write the same value.
        INFO_BITS.store(info_to_bits(info), Ordering::Relaxed);

        // The `Release` here "publishes" the store of `INFO_BITS` to other
        // threads (which do a `INITIALIZED.load(Acquire)`) despite it being
        // read/written w/ `Relaxed`.
        INITIALIZED.store(true, Ordering::Release);
        info
    }

    #[inline]
    fn info_to_bits(info: mach_timebase_info) -> u64 {
        ((info.denom as u64) << 32) | (info.numer as u64)
    }

    #[inline]
    fn info_from_bits(bits: u64) -> mach_timebase_info {
        mach_timebase_info { numer: bits as u32, denom: (bits >> 32) as u32 }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use crate::fmt;
    use crate::sys::cvt;
    use crate::time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub const fn zero() -> Instant {
            Instant { t: Timespec::zero() }
        }

        pub fn actually_monotonic() -> bool {
            (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
                || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
                || cfg!(target_os = "fuchsia")
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            self.t.sub_timespec(&other.t).ok()
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Instant")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
        cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
        t
    }
}
<commit_msg>Switch to using a single atomic and treating 0 as 'uninitialized'<commit_after>use crate::cmp::Ordering;
use crate::time::Duration;

use core::hash::{Hash, Hasher};

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
use crate::convert::TryInto;

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    const fn zero() -> Timespec {
        Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }
    }

    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
            // to optimize it into a branchless form (see also #75545):
            //
            // 1. `self.t.tv_sec - other.t.tv_sec` shows up as a common expression
            //    in both branches, i.e. the `else` must have its `- 1`
            //    subtraction after the common one, not interleaved with it
            //    (it used to be `self.t.tv_sec - 1 - other.t.tv_sec`)
            //
            // 2. the `Duration::new` call (or any other additional complexity)
            //    is outside of the `if`-`else`, not duplicated in both branches
            //
            // Ideally this code could be rearranged such that it more
            // directly expresses the lower-cost behavior we want from it.
            let (secs, nsec) = if self.t.tv_nsec >= other.t.tv_nsec {
                ((self.t.tv_sec - other.t.tv_sec) as u64, (self.t.tv_nsec - other.t.tv_nsec) as u32)
            } else {
                (
                    (self.t.tv_sec - other.t.tv_sec - 1) as u64,
                    self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
                )
            };

            Ok(Duration::new(secs, nsec))
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }

    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
        let mut secs = other
            .as_secs()
            .try_into() // <- target type would be `libc::time_t`
            .ok()
            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1)?;
        }
        Some(Timespec { t: libc::timespec { tv_sec: secs, tv_nsec: nsec as _ } })
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

impl Hash for Timespec {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.t.tv_sec.hash(state);
        self.t.tv_nsec.hash(state);
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use crate::fmt;
    use crate::sync::atomic::{AtomicU64, Ordering};
    use crate::sys::cvt;
    use crate::sys_common::mul_div_u64;
    use crate::time::Duration;

    use super::Timespec;
    use super::NSEC_PER_SEC;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
    pub struct Instant {
        t: u64,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    #[repr(C)]
    #[derive(Copy, Clone)]
    struct mach_timebase_info {
        numer: u32,
        denom: u32,
    }
    type mach_timebase_info_t = *mut mach_timebase_info;
    type kern_return_t = libc::c_int;

    impl Instant {
        pub fn now() -> Instant {
            extern "C" {
                fn mach_absolute_time() -> u64;
            }
            Instant { t: unsafe { mach_absolute_time() } }
        }

        pub const fn zero() -> Instant {
            Instant { t: 0 }
        }

        pub fn actually_monotonic() -> bool {
            true
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            let diff = self.t.checked_sub(other.t)?;
            let info = info();
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32))
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? })
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use crate::ptr;

            let mut s = libc::timeval { tv_sec: 0, tv_usec: 0 };
            cvt(unsafe { libc::gettimeofday(&mut s, ptr::null_mut()) }).unwrap();
            return SystemTime::from(s);
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    fn checked_dur2intervals(dur: &Duration) -> Option<u64> {
        let nanos =
            dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as u64)?;
        let info = info();
        Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
    }

    fn info() -> mach_timebase_info {
        // INFO_BITS conceptually is an `Option<mach_timebase_info>`. We can do
        // this in 64 bits because we know 0 is never a valid value for the
        // `denom` field.
        //
        // Encoding this as a single `AtomicU64` allows us to use `Relaxed`
        // operations, as we are only interested in in the effects on a single
        // memory location.
        static INFO_BITS: AtomicU64 = AtomicU64::new(0);

        // If a previous thread has initialized `INFO_BITS`, use it.
        let info_bits = INFO_BITS.load(Ordering::Relaxed);
        if info_bits != 0 {
            return info_from_bits(info_bits);
        }

        // ... otherwise learn for ourselves ...
        extern "C" {
            fn mach_timebase_info(info: mach_timebase_info_t) -> kern_return_t;
        }

        let mut info = info_from_bits(0);
        unsafe {
            mach_timebase_info(&mut info);
        }
        INFO_BITS.store(info_to_bits(info), Ordering::Relaxed);
        info
    }

    #[inline]
    fn info_to_bits(info: mach_timebase_info) -> u64 {
        ((info.denom as u64) << 32) | (info.numer as u64)
    }

    #[inline]
    fn info_from_bits(bits: u64) -> mach_timebase_info {
        mach_timebase_info { numer: bits as u32, denom: (bits >> 32) as u32 }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use crate::fmt;
    use crate::sys::cvt;
    use crate::time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub const fn zero() -> Instant {
            Instant { t: Timespec::zero() }
        }

        pub fn actually_monotonic() -> bool {
            (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
                || (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
                || cfg!(target_os = "fuchsia")
        }

        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
            self.t.sub_timespec(&other.t).ok()
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
            Some(Instant { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Instant")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_add_duration(other)? })
        }

        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("SystemTime")
                .field("tv_sec", &self.t.t.tv_sec)
                .field("tv_nsec", &self.t.t.tv_nsec)
                .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } };
        cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap();
        t
    }
}
<|endoftext|>


<commit_before>use petgraph::{Graph, Undirected};
use rand;
use rand::distributions::{IndependentSample, Range};

pub type GridIndexType = u16;
pub type GridGraphNodeIndex = ::petgraph::graph::NodeIndex<GridIndexType>;

pub enum GridDirection {
    North,
    South,
    East,
    West,
}

struct AdjacentCells {
    north: Option<GridGraphNodeIndex>,
    south: Option<GridGraphNodeIndex>,
    east: Option<GridGraphNodeIndex>,
    west: Option<GridGraphNodeIndex>,
}
impl AdjacentCells {
    fn new() -> Self {
        AdjacentCells {
            north: None,
            south: None,
            east: None,
            west: None,
        }
    }
}

#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
struct GridCoordinate {
    pub x: isize,
    pub y: isize,
}

pub struct SquareGrid {
    /// For mapping a 2D gridcoordinate (converted to a 1D index) to a graph node index.
    grid_coordinate_to_node_index_lookup: Vec<GridGraphNodeIndex>,
    graph: Graph<AdjacentCells, (), Undirected, GridIndexType>,
    dimension_size: GridIndexType,
}

impl SquareGrid {
    pub fn new(dimension_size: GridIndexType) -> SquareGrid {

        let cells_count = dimension_size * dimension_size;
        let nodes_count_hint = cells_count as usize;
        let edges_count_hint = 4 * cells_count as usize - 4 * dimension_size as usize; // Probably overkill, but don't want any capacity panics

        let mut grid = SquareGrid {
            grid_coordinate_to_node_index_lookup: Vec::with_capacity(nodes_count_hint),
            graph: Graph::with_capacity(nodes_count_hint, edges_count_hint),
            dimension_size: dimension_size,
        };

        // Although it does seem to, there is no guarantee that the index values are monotonically increasing when calling graph.add_node
        // So we maintain our own symbol table mapping gridcoordinates converted to 1d (the implicit Vec indices) to the NodeIndexes created
        // by adding a node to the graph.
        for _ in 0..cells_count {
            let node_index = grid.graph.add_node(AdjacentCells::new());
            grid.grid_coordinate_to_node_index_lookup.push(node_index);
        }

        for (index, node_index) in grid.grid_coordinate_to_node_index_lookup.iter().enumerate() {

            let coord = grid.index_to_grid_coordinate(index);

            // Limit the lifetime of the find_neighbour_nodeindex closure so we don't get a grid
            // borrow conflict when mutating the adjacent_cells
            let (north_index, south_index, east_index, west_index) = {
                let find_neighbour_nodeindex = |dir: GridDirection| -> Option<GridGraphNodeIndex> {
                    let neighbour_coord = offset_coordinate(&coord, dir);
                    if grid.is_valid_coordinate(&neighbour_coord) {
                        let node_indices_index = grid.grid_coordinate_to_1d_index(&neighbour_coord);
                        let node_index =
                            grid.grid_coordinate_to_node_index_lookup[node_indices_index as usize];
                        Some(node_index)
                    } else {
                        None
                    }
                };
                (find_neighbour_nodeindex(GridDirection::North),
                 find_neighbour_nodeindex(GridDirection::South),
                 find_neighbour_nodeindex(GridDirection::East),
                 find_neighbour_nodeindex(GridDirection::West))
            };

            let adjacent_cells = grid.graph
                                     .node_weight_mut(node_index.clone())
                                     .unwrap();
            adjacent_cells.north = north_index;
            adjacent_cells.south = south_index;
            adjacent_cells.east = east_index;
            adjacent_cells.west = west_index;
        }

        grid
    }

    pub fn random_cell(&self) -> GridGraphNodeIndex {
        let random_pos = Range::new(0, self.grid_coordinate_to_node_index_lookup.len());
        let mut rng = rand::thread_rng();
        let index = random_pos.ind_sample(&mut rng);
        self.grid_coordinate_to_node_index_lookup[index]
    }

    /// Link two cells
    ///
    /// Todo - only allow links between adjacent cells? If `b` not in `g.neighbours(a)`.
    ///      - better to change the API to take an index and GridDirection
    ///
    /// Panics if a cell does not exist.
    pub fn link(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {
        if a != b {
            let _ = self.graph.update_edge(a, b, ());
        }
    }

    /// Unlink two cells, if a link exists between them.
    pub fn unlink(&mut self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) {

        if let Some(edge_index) = self.graph.find_edge(a, b) {
            // This will invalidate the last edge index in the graph, which is fine as we
            // are not storing them for any reason.
            self.graph.remove_edge(edge_index);
        }
    }

    /// Cell nodes that are linked to a particular node by a passage.
    pub fn links(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {
        self.graph
            .edges(node_index)
            .map(|index_edge_data_pair| index_edge_data_pair.0.clone())
            .collect()
    }

    /// Cell nodes that are to the North, South, East or West of a particular node, but not
    /// necessarily linked by a passage.
    pub fn neighbours(&self, node_index: GridGraphNodeIndex) -> Vec<GridGraphNodeIndex> {

        if let Some(adj) = self.graph.node_weight(node_index) {
            vec![adj.north, adj.south, adj.east, adj.west]
                .iter()
                .filter_map(|&maybe_adj| maybe_adj.clone())
                .collect()
        } else {
            vec![]
        }
    }

    fn is_neighbour(&self, a: GridGraphNodeIndex, b: GridGraphNodeIndex) -> bool {
        macro_rules! index_node_match {
            ($opt_grid_index:expr) => (if let Some(node_index) = $opt_grid_index {
                                           if node_index == b {
                                               return true;
                                           }
                                       })
        }
        if let Some(adjacents_of_a) = self.graph.node_weight(a) {
            index_node_match!(adjacents_of_a.north);
            index_node_match!(adjacents_of_a.south);
            index_node_match!(adjacents_of_a.east);
            index_node_match!(adjacents_of_a.west);
        }
        false
    }

    fn is_valid_coordinate(&self, coord: &GridCoordinate) -> bool {
        let (x, y) = (coord.x, coord.y);
        let dim_size = self.dimension_size as isize;
        if x < 0 || y < 0 || x >= dim_size || y >= dim_size {
            return false;
        }
        true
    }

    fn grid_coordinate_to_1d_index(&self, coord: &GridCoordinate) -> GridIndexType {
        ((coord.y * self.dimension_size as isize) + coord.x) as GridIndexType
    }

    fn index_to_grid_coordinate(&self, one_dimensional_index: usize) -> GridCoordinate {
        let dim_size = self.dimension_size as usize;
        let y = one_dimensional_index / dim_size;
        let x = one_dimensional_index - (y * dim_size);
        GridCoordinate {
            x: x as isize,
            y: y as isize,
        }
    }
}

fn offset_coordinate(coord: &GridCoordinate, dir: GridDirection) -> GridCoordinate {
    let (x, y) = (coord.x, coord.y);
    match dir {
        GridDirection::North => GridCoordinate { x: x, y: y - 1 },
        GridDirection::South => GridCoordinate { x: x, y: y + 1 },
        GridDirection::East => GridCoordinate { x: x + 1, y: y },
        GridDirection::West => GridCoordinate { x: x - 1, y: y },
    }
}

#[cfg(test)]
mod test {

    use super::*;
    use itertools::Itertools; // a trait

    #[test]
    fn neighbour_cells() {
        let g = SquareGrid::new(10);

        let check_expected_neighbours = |node_index, vec_expected_neighbour_indices: Vec<usize>| {
            let node_indices = g.neighbours(GridGraphNodeIndex::new(node_index))
                                .into_iter()
                                .sorted();
            let expected_indices =
                vec_expected_neighbour_indices.into_iter()
                                              .sorted()
                                              .into_iter()
                                              .map(|index: usize| GridGraphNodeIndex::new(index))
                                              .collect::<Vec<GridGraphNodeIndex>>();
            assert_eq!(node_indices, expected_indices);
        };

        // corners
        check_expected_neighbours(0, vec![1, 10]);
        check_expected_neighbours(9, vec![8, 19]);
        check_expected_neighbours(90, vec![80, 91]);
        check_expected_neighbours(99, vec![89, 98]);

        // side element examples
        check_expected_neighbours(10, vec![0, 11, 20]);
        check_expected_neighbours(1, vec![0, 2, 11]);
        check_expected_neighbours(80, vec![70, 81, 90]);
        check_expected_neighbours(89, vec![79, 88, 99]);
        check_expected_neighbours(19, vec![9, 18, 29]);
        check_expected_neighbours(8, vec![7, 9, 18]);

        // Some place with 4 neighbours inside the grid
        check_expected_neighbours(12, vec![2, 11, 13, 22]);
    }

    #[test]
    fn random_cell() {
        let g = SquareGrid::new(4);
        let cells_count = 4 * 4;
        for _ in 0..1000 {
            let grid_index = g.random_cell();
            assert!(grid_index.index() >= 0 && grid_index.index() < cells_count);
        }
    }

    #[test]
    fn linking_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridGraphNodeIndex::new(0);
        let b = GridGraphNodeIndex::new(1);
        let c = GridGraphNodeIndex::new(2);

        // I'd rather use a closure, but it needs to borrow the graph immutably until
        // it goes out of scope
        // Passing the graph in allows me to use a plain function:
        // let links_sorted = |n: GridGraphNodeIndex, g: &SquareGrid| -> Vec<GridGraphNodeIndex> {
        //     g.links(n).into_iter().sorted()
        // };
        // but it's uglier in that I need to explicitly pass in the SquareGrid ref all the time
        macro_rules! links_sorted {
            ($x:expr) => (g.links($x).into_iter().sorted())
        }

        // a, b and c start with no links
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        g.link(a, b);
        // a - b linked bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a]);

        g.link(b, c);
        // a - b still linked bi-directionally after linking b - c
        // b linked to a & c bi-directionally
        // c linked to b bi-directionally
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a - b still linked bi-directionally after updating exist link
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);

        // a - b unlinked
        // b still linked to c bi-directionally
        g.unlink(a, b);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a, b and c start all unlinked again
        g.unlink(b, c);
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);
    }

    #[test]
    fn no_self_linked_cycles() {
        let mut g = SquareGrid::new(4);
        let a = GridGraphNodeIndex::new(0);
        g.link(a, a);
        assert_eq!(g.links(a), vec![]);
    }

    #[test]
    fn no_parallel_duplicated_linked_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridGraphNodeIndex::new(0);
        let b = GridGraphNodeIndex::new(1);
        g.link(a, b);
        g.link(a, b);
        assert_eq!(g.links(a), vec![b]);
        assert_eq!(g.links(b), vec![a]);

        g.unlink(a, b);
        assert_eq!(g.links(a), vec![]);
        assert_eq!(g.links(b), vec![]);
    }
}
<commit_msg>Refactor square grid to use GridCoordinates as the main end user type.<commit_after>use petgraph::{Graph, Undirected};
use rand;
use rand::distributions::{IndependentSample, Range};

pub type GridIndexType = u16;
pub type GridGraphNodeIndex = ::petgraph::graph::NodeIndex<GridIndexType>;

enum GridDirection {
    North,
    South,
    East,
    West,
}

#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone, Ord, PartialOrd)]
pub struct GridCoordinate {
    pub x: isize,
    pub y: isize,
}
impl GridCoordinate {
    pub fn new(x: isize, y: isize) -> GridCoordinate {
        GridCoordinate { x: x, y: y }
    }
}

pub struct SquareGrid {
    graph: Graph<(), (), Undirected, GridIndexType>,
    dimension_size: GridIndexType,
}
impl SquareGrid {
    pub fn new(dimension_size: GridIndexType) -> SquareGrid {

        let cells_count = dimension_size * dimension_size;
        let nodes_count_hint = cells_count as usize;
        let edges_count_hint = 4 * cells_count as usize - 4 * dimension_size as usize; // Probably overkill, but don't want any capacity panics

        let mut grid = SquareGrid {
            graph: Graph::with_capacity(nodes_count_hint, edges_count_hint),
            dimension_size: dimension_size,
        };
        for _ in 0..cells_count {
            let _ = grid.graph.add_node(());
        }

        grid
    }

    pub fn random_cell(&self) -> GridCoordinate {
        let range_end_exclusive = self.dimension_size as usize * self.dimension_size as usize;
        let random_pos = Range::new(0, range_end_exclusive);
        let mut rng = rand::thread_rng();
        let index = random_pos.ind_sample(&mut rng);
        index_to_grid_coordinate(self.dimension_size as usize, index)
    }

    /// Link two cells
    ///
    /// Todo - only allow links between adjacent cells? If `b` not in `g.neighbours(a)`.
    ///      - better to change the API to take an index and GridDirection
    ///
    /// Panics if a cell does not exist.
    pub fn link(&mut self, a: GridCoordinate, b: GridCoordinate) {
        if a != b {
            let a_index = self.grid_coordinate_graph_index(&a);
            let b_index = self.grid_coordinate_graph_index(&b);
            let _ = self.graph.update_edge(a_index, b_index, ());
        }
    }

    /// Unlink two cells, if a link exists between them.
    pub fn unlink(&mut self, a: GridCoordinate, b: GridCoordinate) {
        let a_index = self.grid_coordinate_graph_index(&a);
        let b_index = self.grid_coordinate_graph_index(&b);
        if let Some(edge_index) = self.graph.find_edge(a_index, b_index) {
            // This will invalidate the last edge index in the graph, which is fine as we
            // are not storing them for any reason.
            self.graph.remove_edge(edge_index);
        }
    }

    /// Cell nodes that are linked to a particular node by a passage.
    pub fn links(&self, coord: GridCoordinate) -> Vec<GridCoordinate> {
        self.graph
            .edges(self.grid_coordinate_graph_index(&coord))
            .map(|index_edge_data_pair| {
                let grid_node_index = index_edge_data_pair.0.clone();
                index_to_grid_coordinate(self.dimension_size as usize, grid_node_index.index())
            })
            .collect()
    }

    /// Cell nodes that are to the North, South, East or West of a particular node, but not
    /// necessarily linked by a passage.
    pub fn neighbours(&self, coord: GridCoordinate) -> Vec<GridCoordinate> {

        vec![offset_coordinate(&coord, GridDirection::North),
             offset_coordinate(&coord, GridDirection::South),
             offset_coordinate(&coord, GridDirection::East),
             offset_coordinate(&coord, GridDirection::West)]
            .into_iter()
            .filter(|adjacent_coord| self.is_valid_coordinate(adjacent_coord))
            .collect()
    }

    /// Are two cells in the grid linked?
    pub fn is_linked(&self, a: GridCoordinate, b: GridCoordinate) -> bool {
        let a_index = self.grid_coordinate_graph_index(&a);
        let b_index = self.grid_coordinate_graph_index(&b);
        self.graph.find_edge(a_index, b_index).is_some()
    }

    pub fn iter(&self) -> CellIter {
        let dim_size = self.dimension_size as usize;
        CellIter {
            current_cell_number: 0,
            dimension_size: dim_size,
            cells_count: dim_size * dim_size
        }
    }

    pub fn iter_row(&self) -> BatchIter {
        BatchIter {
            iter_type: BatchIterType::Row,
            current_index: 0,
            dimension_size: self.dimension_size as usize
        }
    }

    pub fn iter_column(&self) -> BatchIter {
        BatchIter {
            iter_type: BatchIterType::Column,
            current_index: 0,
            dimension_size: self.dimension_size as usize
        }
    }

    fn is_neighbour(&self, a: GridCoordinate, b: GridCoordinate) -> bool {
        self.neighbours(a).iter().any(|&coord| coord == b)
    }

    fn is_valid_coordinate(&self, coord: &GridCoordinate) -> bool {
        let (x, y) = (coord.x, coord.y);
        let dim_size = self.dimension_size as isize;
        if x < 0 || y < 0 || x >= dim_size || y >= dim_size {
            return false;
        }
        true
    }

    fn grid_coordinate_graph_index(&self, coord: &GridCoordinate) -> GridGraphNodeIndex {
        let grid_index_raw = ((coord.y * self.dimension_size as isize) + coord.x) as usize;
        GridGraphNodeIndex::new(grid_index_raw)
    }
}

pub struct CellIter {
    current_cell_number: usize,
    dimension_size: usize,
    cells_count: usize
}
impl Iterator for CellIter {
    type Item = GridCoordinate;
    fn next(&mut self) -> Option<Self::Item> {
        if self.current_cell_number < self.cells_count {
            let coord = index_to_grid_coordinate(self.dimension_size, self.current_cell_number);
            self.current_cell_number += 1;
            Some(coord)
        }
        else {
            None
        }
    }
}

enum BatchIterType {
    Row,
    Column
}
pub struct BatchIter {
    iter_type: BatchIterType,
    current_index: usize,
    dimension_size: usize,
}
impl Iterator for BatchIter {
    type Item = Vec<GridCoordinate>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.current_index < self.dimension_size {
            let coords = (0..self.dimension_size)
                                 .into_iter()
                                 .map(|i| match self.iter_type {
                                    BatchIterType::Row    => GridCoordinate::new(i as isize, self.current_index as isize),
                                    BatchIterType::Column => GridCoordinate::new(self.current_index as isize, i as isize)
                                  })
                                 .collect();
            self.current_index += 1;
            Some(coords)
        } else {
            None
        }
    }
}

fn index_to_grid_coordinate(dimension_size: usize, one_dimensional_index: usize) -> GridCoordinate {
    let y = one_dimensional_index / dimension_size;
    let x = one_dimensional_index - (y * dimension_size);
    GridCoordinate {
        x: x as isize,
        y: y as isize,
    }
}

fn offset_coordinate(coord: &GridCoordinate, dir: GridDirection) -> GridCoordinate {
    let (x, y) = (coord.x, coord.y);
    match dir {
        GridDirection::North => GridCoordinate { x: x, y: y - 1 },
        GridDirection::South => GridCoordinate { x: x, y: y + 1 },
        GridDirection::East => GridCoordinate { x: x + 1, y: y },
        GridDirection::West => GridCoordinate { x: x - 1, y: y },
    }
}

#[cfg(test)]
mod test {

    use super::*;
    use itertools::Itertools; // a trait

    #[test]
    fn neighbour_cells() {
        let g = SquareGrid::new(10);

        let check_expected_neighbours = |coord, vec_expected_neighbours: Vec<GridCoordinate>| {
            let node_indices = g.neighbours(coord)
                                .into_iter()
                                .sorted();
            let expected_indices = vec_expected_neighbours.into_iter()
                                                          .sorted();
            assert_eq!(node_indices, expected_indices);
        };
        let gc = |x, y| GridCoordinate::new(x, y);

        // corners
        check_expected_neighbours(gc(0, 0), vec![gc(1, 0), gc(0, 1)]);
        check_expected_neighbours(gc(9, 0), vec![gc(8, 0), gc(9, 1)]);
        check_expected_neighbours(gc(0, 9), vec![gc(0, 8), gc(1, 9)]);
        check_expected_neighbours(gc(9, 9), vec![gc(9, 8), gc(8, 9)]);

        // side element examples
        check_expected_neighbours(gc(1, 0), vec![gc(0, 0), gc(1, 1), gc(2, 0)]);
        check_expected_neighbours(gc(0, 1), vec![gc(0, 0), gc(0, 2), gc(1, 1)]);
        check_expected_neighbours(gc(0, 8), vec![gc(1, 8), gc(0, 7), gc(0, 9)]);
        check_expected_neighbours(gc(9, 8), vec![gc(9, 7), gc(9, 9), gc(8, 8)]);

        // Some place with 4 neighbours inside the grid
        check_expected_neighbours(gc(1, 1), vec![gc(0, 1), gc(1, 0), gc(2, 1), gc(1, 2)]);
    }

    #[test]
    fn random_cell() {
        let g = SquareGrid::new(4);
        let cells_count = 4 * 4;
        for _ in 0..1000 {
            let coord = g.random_cell();
            assert!(coord.x >= 0 && coord.x < cells_count);
            assert!(coord.y >= 0 && coord.y < cells_count);
        }
    }

    #[test]
    fn linking_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridCoordinate::new(0, 1);
        let b = GridCoordinate::new(0, 2);
        let c = GridCoordinate::new(0, 3);

        // I'd rather use a closure, but it needs to borrow the graph immutably until
        // it goes out of scope
        // Passing the graph in allows me to use a plain function:
        // let links_sorted = |n: GridGraphNodeIndex, g: &SquareGrid| -> Vec<GridGraphNodeIndex> {
        //     g.links(n).into_iter().sorted()
        // };
        // but it's uglier in that I need to explicitly pass in the SquareGrid ref all the time
        macro_rules! links_sorted {
            ($x:expr) => (g.links($x).into_iter().sorted())
        }
        // Testing that the order of the arguments to `is_linked` does not matter
        macro_rules! bi_check_linked {
            ($x:expr, $y:expr) => (g.is_linked($x, $y) && g.is_linked($y, $x))
        }

        // a, b and c start with no links
        assert!(!bi_check_linked!(a, b));
        assert!(!bi_check_linked!(a, c));
        assert!(!bi_check_linked!(b, c));
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);

        g.link(a, b);
        // a - b linked bi-directionally
        assert!(bi_check_linked!(a, b));
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a]);

        g.link(b, c);
        // a - b still linked bi-directionally after linking b - c
        // b linked to a & c bi-directionally
        // c linked to b bi-directionally
        assert!(bi_check_linked!(a, b));
        assert!(bi_check_linked!(b, c));
        assert!(!bi_check_linked!(a, c));
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a - b still linked bi-directionally after updating exist link
        assert!(bi_check_linked!(a, b));
        assert!(bi_check_linked!(b, c));
        assert_eq!(links_sorted!(a), vec![b]);
        assert_eq!(links_sorted!(b), vec![a, c]);

        // a - b unlinked
        // b still linked to c bi-directionally
        g.unlink(a, b);
        assert!(!bi_check_linked!(a, b));
        assert!(bi_check_linked!(b, c));
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![c]);
        assert_eq!(links_sorted!(c), vec![b]);

        // a, b and c start all unlinked again
        g.unlink(b, c);
        assert!(!bi_check_linked!(a, b));
        assert!(!bi_check_linked!(a, c));
        assert!(!bi_check_linked!(b, c));
        assert_eq!(links_sorted!(a), vec![]);
        assert_eq!(links_sorted!(b), vec![]);
        assert_eq!(links_sorted!(c), vec![]);
    }

    #[test]
    fn no_self_linked_cycles() {
        let mut g = SquareGrid::new(4);
        let a = GridCoordinate::new(0, 0);
        g.link(a, a);
        assert_eq!(g.links(a), vec![]);
    }

    #[test]
    fn no_parallel_duplicated_linked_cells() {
        let mut g = SquareGrid::new(4);
        let a = GridCoordinate::new(0, 0);
        let b = GridCoordinate::new(0, 1);
        g.link(a, b);
        g.link(a, b);
        assert_eq!(g.links(a), vec![b]);
        assert_eq!(g.links(b), vec![a]);

        g.unlink(a, b);
        assert_eq!(g.links(a), vec![]);
        assert_eq!(g.links(b), vec![]);
    }
}
<|endoftext|>


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

//! Abstractions for global scopes.

use dom::bindings::js::{JS, JSRef, Root};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::window::Window;
use page::Page;
use script_task::ScriptChan;

use js::jsapi::JSContext;

use url::Url;

pub enum GlobalRef<'a> {
    Window(JSRef<'a, Window>),
}

pub enum GlobalRoot<'a, 'b> {
    WindowRoot(Root<'a, 'b, Window>),
}

#[deriving(Encodable)]
pub enum GlobalField {
    WindowField(JS<Window>),
}

impl<'a> GlobalRef<'a> {
    pub fn get_cx(&self) -> *mut JSContext {
        match *self {
            Window(ref window) => window.get_cx(),
        }
    }

    pub fn as_window<'b>(&'b self) -> &'b JSRef<'b, Window> {
        match *self {
            Window(ref window) => window,
        }
    }

    pub fn page<'b>(&'b self) -> &'b Page {
        self.as_window().page()
    }
    pub fn get_url(&self) -> Url {
        self.as_window().get_url()
    }
    pub fn script_chan<'b>(&'b self) -> &'b ScriptChan {
        &self.as_window().script_chan
    }
}

impl<'a> Reflectable for GlobalRef<'a> {
    fn reflector<'b>(&'b self) -> &'b Reflector {
        match *self {
            Window(ref window) => window.reflector(),
        }
    }
}

impl<'a, 'b> GlobalRoot<'a, 'b> {
    pub fn root_ref<'c>(&'c self) -> GlobalRef<'c> {
        match *self {
            WindowRoot(ref window) => Window(window.root_ref()),
        }
    }
}

impl GlobalField {
    pub fn from_rooted(global: &GlobalRef) -> GlobalField {
        match *global {
            Window(ref window) => WindowField(JS::from_rooted(window)),
        }
    }

    pub fn root(&self) -> GlobalRoot {
        match *self {
            WindowField(ref window) => WindowRoot(window.root()),
        }
    }
}
<commit_msg>Add newlines in global.rs.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Abstractions for global scopes.

use dom::bindings::js::{JS, JSRef, Root};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::window::Window;
use page::Page;
use script_task::ScriptChan;

use js::jsapi::JSContext;

use url::Url;

pub enum GlobalRef<'a> {
    Window(JSRef<'a, Window>),
}

pub enum GlobalRoot<'a, 'b> {
    WindowRoot(Root<'a, 'b, Window>),
}

#[deriving(Encodable)]
pub enum GlobalField {
    WindowField(JS<Window>),
}

impl<'a> GlobalRef<'a> {
    pub fn get_cx(&self) -> *mut JSContext {
        match *self {
            Window(ref window) => window.get_cx(),
        }
    }

    pub fn as_window<'b>(&'b self) -> &'b JSRef<'b, Window> {
        match *self {
            Window(ref window) => window,
        }
    }

    pub fn page<'b>(&'b self) -> &'b Page {
        self.as_window().page()
    }

    pub fn get_url(&self) -> Url {
        self.as_window().get_url()
    }

    pub fn script_chan<'b>(&'b self) -> &'b ScriptChan {
        &self.as_window().script_chan
    }
}

impl<'a> Reflectable for GlobalRef<'a> {
    fn reflector<'b>(&'b self) -> &'b Reflector {
        match *self {
            Window(ref window) => window.reflector(),
        }
    }
}

impl<'a, 'b> GlobalRoot<'a, 'b> {
    pub fn root_ref<'c>(&'c self) -> GlobalRef<'c> {
        match *self {
            WindowRoot(ref window) => Window(window.root_ref()),
        }
    }
}

impl GlobalField {
    pub fn from_rooted(global: &GlobalRef) -> GlobalField {
        match *global {
            Window(ref window) => WindowField(JS::from_rooted(window)),
        }
    }

    pub fn root(&self) -> GlobalRoot {
        match *self {
            WindowField(ref window) => WindowRoot(window.root()),
        }
    }
}
<|endoftext|>


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

use dom::bindings::utils::{Reflectable, DOMString, ErrorResult};
use dom::element::HTMLFormElementTypeId;
use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, ElementNodeTypeId, Node, ScriptView};

use js::jsapi::{JSObject, JSContext};

pub struct HTMLFormElement {
    htmlelement: HTMLElement
}

impl HTMLFormElement {
    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let doc = self.htmlelement.element.node.owner_doc.unwrap();
        let win = doc.with_base(|doc| doc.window.unwrap());
        let cx = win.page.js_info.get_ref().js_compartment.cx.ptr;
        let scope = win.reflector().get_jsobject();
        (scope, cx)
    }

    pub fn AcceptCharset(&self) -> DOMString {
        None
    }

    pub fn SetAcceptCharset(&mut self, _accept_charset: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Action(&self) -> DOMString {
        None
    }

    pub fn SetAction(&mut self, _action: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Autocomplete(&self) -> DOMString {
        None
    }

    pub fn SetAutocomplete(&mut self, _autocomplete: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Enctype(&self) -> DOMString {
        None
    }

    pub fn SetEnctype(&mut self, _enctype: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Encoding(&self) -> DOMString {
        None
    }

    pub fn SetEncoding(&mut self, _encoding: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Method(&self) -> DOMString {
        None
    }

    pub fn SetMethod(&mut self, _method: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Name(&self) -> DOMString {
        None
    }

    pub fn SetName(&mut self, _name: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn NoValidate(&self) -> bool {
        false
    }

    pub fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult {
        Ok(())
    }

    pub fn Target(&self) -> DOMString {
        None
    }

    pub fn SetTarget(&mut self, _target: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Elements(&self) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn Length(&self) -> i32 {
        0
    }

    pub fn Submit(&self) -> ErrorResult {
        Ok(())
    }

    pub fn Reset(&self) {
    }

    pub fn CheckValidity(&self) -> bool {
        false
    }

    pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> AbstractNode<ScriptView> {
        fail!("Not implemented.")
    }
}
<commit_msg>Remove unused imports in htmlformelement<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::utils::{Reflectable, DOMString, ErrorResult};
use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, ScriptView};

use js::jsapi::{JSObject, JSContext};

pub struct HTMLFormElement {
    htmlelement: HTMLElement
}

impl HTMLFormElement {
    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let doc = self.htmlelement.element.node.owner_doc.unwrap();
        let win = doc.with_base(|doc| doc.window.unwrap());
        let cx = win.page.js_info.get_ref().js_compartment.cx.ptr;
        let scope = win.reflector().get_jsobject();
        (scope, cx)
    }

    pub fn AcceptCharset(&self) -> DOMString {
        None
    }

    pub fn SetAcceptCharset(&mut self, _accept_charset: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Action(&self) -> DOMString {
        None
    }

    pub fn SetAction(&mut self, _action: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Autocomplete(&self) -> DOMString {
        None
    }

    pub fn SetAutocomplete(&mut self, _autocomplete: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Enctype(&self) -> DOMString {
        None
    }

    pub fn SetEnctype(&mut self, _enctype: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Encoding(&self) -> DOMString {
        None
    }

    pub fn SetEncoding(&mut self, _encoding: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Method(&self) -> DOMString {
        None
    }

    pub fn SetMethod(&mut self, _method: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Name(&self) -> DOMString {
        None
    }

    pub fn SetName(&mut self, _name: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn NoValidate(&self) -> bool {
        false
    }

    pub fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult {
        Ok(())
    }

    pub fn Target(&self) -> DOMString {
        None
    }

    pub fn SetTarget(&mut self, _target: &DOMString) -> ErrorResult {
        Ok(())
    }

    pub fn Elements(&self) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn Length(&self) -> i32 {
        0
    }

    pub fn Submit(&self) -> ErrorResult {
        Ok(())
    }

    pub fn Reset(&self) {
    }

    pub fn CheckValidity(&self) -> bool {
        false
    }

    pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> AbstractNode<ScriptView> {
        fail!("Not implemented.")
    }
}
<|endoftext|>


<commit_before>use conduit_test::MockRequest;
use conduit::{mod, Handler};

use cargo_registry::user::{User, EncodableUser};

#[deriving(Decodable)]
struct AuthResponse { url: String, state: String }
#[deriving(Decodable)]
struct TokenResponse { ok: bool, error: Option<String> }
#[deriving(Decodable)]
struct MeResponse { ok: bool, user: EncodableUser }

#[test]
fn auth_gives_a_token() {
    let middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/authorize_url");
    let mut response = t_resp!(middle.call(&mut req));
    let json: AuthResponse = ::json(&mut response);
    assert!(json.url.as_slice().contains(json.state.as_slice()));
}

#[test]
fn access_token_needs_data() {
    let middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/authorize");
    let mut response = t_resp!(middle.call(&mut req));
    let json: TokenResponse = ::json(&mut response);
    assert!(!json.ok);
    assert!(json.error.is_some());
    assert!(json.error.unwrap().as_slice().contains("invalid state"));
}

#[test]
fn user_insert() {
    let app = ::app();
    let conn = t!(app.database.get());
    let tx = t!(conn.transaction());

    let user = t!(User::find_or_insert(&tx, "foo", "bar"));
    assert_eq!(t!(User::find_by_api_token(&tx, user.api_token.as_slice())),
               user);
    assert_eq!(t!(User::find(&tx, user.id)), user);

    assert_eq!(t!(User::find_or_insert(&tx, "foo", "bar")), user);
    let user2 = t!(User::find_or_insert(&tx, "foo", "baz"));
    assert!(user != user2);
    assert_eq!(user2.gh_access_token.as_slice(), "baz");
}

#[test]
fn me() {
    let mut middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/me");
    let response = t!(middle.call(&mut req).map_err(|e| (&*e).to_string()));
    assert_eq!(response.status.val0(), 403);

    let user = ::user();
    middle.add(::middleware::MockUser(user.clone()));
    let mut response = t_resp!(middle.call(&mut req));
    let json: MeResponse = ::json(&mut response);
    assert!(json.ok);
    assert_eq!(json.user.email, user.email);
    assert_eq!(json.user.api_token, user.api_token);
    assert_eq!(json.user.id, user.id);
}
<commit_msg>Add a reset token test<commit_after>use std::fmt::Show;

use conduit::{mod, Handler, Request, Response};
use conduit_middleware::Middleware;
use conduit_test::MockRequest;

use cargo_registry::user::{User, EncodableUser};
use cargo_registry::db::RequestTransaction;

#[deriving(Decodable)]
struct AuthResponse { url: String, state: String }
#[deriving(Decodable)]
struct TokenResponse { ok: bool, error: Option<String> }
#[deriving(Decodable)]
struct MeResponse { ok: bool, user: EncodableUser }

#[test]
fn auth_gives_a_token() {
    let middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/authorize_url");
    let mut response = t_resp!(middle.call(&mut req));
    let json: AuthResponse = ::json(&mut response);
    assert!(json.url.as_slice().contains(json.state.as_slice()));
}

#[test]
fn access_token_needs_data() {
    let middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/authorize");
    let mut response = t_resp!(middle.call(&mut req));
    let json: TokenResponse = ::json(&mut response);
    assert!(!json.ok);
    assert!(json.error.is_some());
    assert!(json.error.unwrap().as_slice().contains("invalid state"));
}

#[test]
fn user_insert() {
    let app = ::app();
    let conn = t!(app.database.get());
    let tx = t!(conn.transaction());

    let user = t!(User::find_or_insert(&tx, "foo", "bar"));
    assert_eq!(t!(User::find_by_api_token(&tx, user.api_token.as_slice())),
               user);
    assert_eq!(t!(User::find(&tx, user.id)), user);

    assert_eq!(t!(User::find_or_insert(&tx, "foo", "bar")), user);
    let user2 = t!(User::find_or_insert(&tx, "foo", "baz"));
    assert!(user != user2);
    assert_eq!(user2.gh_access_token.as_slice(), "baz");
}

#[test]
fn me() {
    let mut middle = ::middleware();
    let mut req = MockRequest::new(conduit::Get, "/me");
    let response = t!(middle.call(&mut req).map_err(|e| (&*e).to_string()));
    assert_eq!(response.status.val0(), 403);

    let user = ::user();
    middle.add(::middleware::MockUser(user.clone()));
    let mut response = t_resp!(middle.call(&mut req));
    let json: MeResponse = ::json(&mut response);
    assert!(json.ok);
    assert_eq!(json.user.email, user.email);
    assert_eq!(json.user.api_token, user.api_token);
    assert_eq!(json.user.id, user.id);
}

#[test]
fn reset_token() {
    struct ResetTokenTest;

    let mut middle = ::middleware();
    middle.add(ResetTokenTest);
    let mut req = MockRequest::new(conduit::Put, "/me/reset_token");
    t_resp!(middle.call(&mut req));

    impl Middleware for ResetTokenTest {
        fn before(&self, req: &mut Request) -> Result<(), Box<Show + 'static>> {
            let user = User::find_or_insert(req.tx().unwrap(), "foo",
                                            "bar").unwrap();
            req.mut_extensions().insert(user);
            Ok(())
        }

        fn after(&self, req: &mut Request,
                 response: Result<Response, Box<Show + 'static>>)
                 -> Result<Response, Box<Show + 'static>> {
            let user = req.extensions().find::<User>().unwrap();
            let u2 = User::find(req.tx().unwrap(), user.id).unwrap();
            assert!(u2.api_token != user.api_token);
            response
        }
    }
}
<|endoftext|>


<commit_before>use crate::cxx_vector::{CxxVector, VectorElement};
use crate::fmt::display;
use crate::kind::Trivial;
use crate::string::CxxString;
use crate::ExternType;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::marker::PhantomData;
use core::mem;
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::ptr;

/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.
#[repr(C)]
pub struct UniquePtr<T>
where
    T: UniquePtrTarget,
{
    repr: *mut c_void,
    ty: PhantomData<T>,
}

impl<T> UniquePtr<T>
where
    T: UniquePtrTarget,
{
    /// Makes a new UniquePtr wrapping a null pointer.
    ///
    /// Matches the behavior of default-constructing a std::unique\_ptr.
    pub fn null() -> Self {
        UniquePtr {
            repr: T::__null(),
            ty: PhantomData,
        }
    }

    /// Allocates memory on the heap and makes a UniquePtr pointing to it.
    pub fn new(value: T) -> Self
    where
        T: ExternType<Kind = Trivial>,
    {
        UniquePtr {
            repr: T::__new(value),
            ty: PhantomData,
        }
    }

    /// Checks whether the UniquePtr does not own an object.
    ///
    /// This is the opposite of [std::unique_ptr\<T\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool).
    pub fn is_null(&self) -> bool {
        let ptr = unsafe { T::__get(self.repr) };
        ptr.is_null()
    }

    /// Returns a reference to the object owned by this UniquePtr if any,
    /// otherwise None.
    pub fn as_ref(&self) -> Option<&T> {
        unsafe { T::__get(self.repr).as_ref() }
    }

    /// Returns a mutable pinned reference to the object owned by this UniquePtr
    /// if any, otherwise None.
    pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
        unsafe {
            let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?;
            Some(Pin::new_unchecked(mut_reference))
        }
    }

    /// Returns a mutable pinned reference to the object owned by this
    /// UniquePtr.
    ///
    /// # Panics
    ///
    /// Panics if the UniquePtr holds a null pointer.
    pub fn pin_mut(&mut self) -> Pin<&mut T> {
        match self.as_mut() {
            Some(target) => target,
            None => panic!(
                "called pin_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }

    /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T.
    ///
    /// Matches the behavior of [std::unique_ptr\<T\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release).
    pub fn into_raw(self) -> *mut T {
        let ptr = unsafe { T::__release(self.repr) };
        mem::forget(self);
        ptr
    }

    /// Constructs a UniquePtr retaking ownership of a pointer previously
    /// obtained from `into_raw`.
    ///
    /// # Safety
    ///
    /// This function is unsafe because improper use may lead to memory
    /// problems. For example a double-free may occur if the function is called
    /// twice on the same raw pointer.
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        UniquePtr {
            repr: T::__raw(raw),
            ty: PhantomData,
        }
    }
}

unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}

impl<T> Drop for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    fn drop(&mut self) {
        unsafe { T::__drop(self.repr) }
    }
}

impl<T> Deref for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match self.as_ref() {
            Some(target) => target,
            None => panic!(
                "called deref on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> DerefMut for UniquePtr<T>
where
    T: UniquePtrTarget + Unpin,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self.as_mut() {
            Some(target) => Pin::into_inner(target),
            None => panic!(
                "called deref_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> Debug for UniquePtr<T>
where
    T: Debug + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Debug::fmt(value, formatter),
        }
    }
}

impl<T> Display for UniquePtr<T>
where
    T: Display + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Display::fmt(value, formatter),
        }
    }
}

// Methods are private; not intended to be implemented outside of cxxbridge
// codebase.
pub unsafe trait UniquePtrTarget {
    #[doc(hidden)]
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
    #[doc(hidden)]
    fn __null() -> *mut c_void;
    #[doc(hidden)]
    fn __new(value: Self) -> *mut c_void
    where
        Self: Sized,
    {
        // Opaque C types do not get this method because they can never exist by
        // value on the Rust side of the bridge.
        let _ = value;
        unreachable!()
    }
    #[doc(hidden)]
    unsafe fn __raw(raw: *mut Self) -> *mut c_void;
    #[doc(hidden)]
    unsafe fn __get(repr: *mut c_void) -> *const Self;
    #[doc(hidden)]
    unsafe fn __release(repr: *mut c_void) -> *mut Self;
    #[doc(hidden)]
    unsafe fn __drop(repr: *mut c_void);
}

extern "C" {
    #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
    fn unique_ptr_std_string_null(this: *mut *mut c_void);
    #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
    fn unique_ptr_std_string_raw(this: *mut *mut c_void, raw: *mut CxxString);
    #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
    fn unique_ptr_std_string_get(this: *const *mut c_void) -> *const CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
    fn unique_ptr_std_string_release(this: *mut *mut c_void) -> *mut CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
    fn unique_ptr_std_string_drop(this: *mut *mut c_void);
}

unsafe impl UniquePtrTarget for CxxString {
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("CxxString")
    }
    fn __null() -> *mut c_void {
        let mut repr = ptr::null_mut::<c_void>();
        unsafe {
            unique_ptr_std_string_null(&mut repr);
        }
        repr
    }
    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
        let mut repr = ptr::null_mut::<c_void>();
        unique_ptr_std_string_raw(&mut repr, raw);
        repr
    }
    unsafe fn __get(repr: *mut c_void) -> *const Self {
        unique_ptr_std_string_get(&repr)
    }
    unsafe fn __release(mut repr: *mut c_void) -> *mut Self {
        unique_ptr_std_string_release(&mut repr)
    }
    unsafe fn __drop(mut repr: *mut c_void) {
        unique_ptr_std_string_drop(&mut repr);
    }
}

unsafe impl<T> UniquePtrTarget for CxxVector<T>
where
    T: VectorElement,
{
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "CxxVector<{}>", display(T::__typename))
    }
    fn __null() -> *mut c_void {
        T::__unique_ptr_null()
    }
    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
        T::__unique_ptr_raw(raw)
    }
    unsafe fn __get(repr: *mut c_void) -> *const Self {
        T::__unique_ptr_get(repr)
    }
    unsafe fn __release(repr: *mut c_void) -> *mut Self {
        T::__unique_ptr_release(repr)
    }
    unsafe fn __drop(repr: *mut c_void) {
        T::__unique_ptr_drop(repr);
    }
}
<commit_msg>Document UniquePtrTarget trait<commit_after>use crate::cxx_vector::{CxxVector, VectorElement};
use crate::fmt::display;
use crate::kind::Trivial;
use crate::string::CxxString;
use crate::ExternType;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::marker::PhantomData;
use core::mem;
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::ptr;

/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.
#[repr(C)]
pub struct UniquePtr<T>
where
    T: UniquePtrTarget,
{
    repr: *mut c_void,
    ty: PhantomData<T>,
}

impl<T> UniquePtr<T>
where
    T: UniquePtrTarget,
{
    /// Makes a new UniquePtr wrapping a null pointer.
    ///
    /// Matches the behavior of default-constructing a std::unique\_ptr.
    pub fn null() -> Self {
        UniquePtr {
            repr: T::__null(),
            ty: PhantomData,
        }
    }

    /// Allocates memory on the heap and makes a UniquePtr pointing to it.
    pub fn new(value: T) -> Self
    where
        T: ExternType<Kind = Trivial>,
    {
        UniquePtr {
            repr: T::__new(value),
            ty: PhantomData,
        }
    }

    /// Checks whether the UniquePtr does not own an object.
    ///
    /// This is the opposite of [std::unique_ptr\<T\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool).
    pub fn is_null(&self) -> bool {
        let ptr = unsafe { T::__get(self.repr) };
        ptr.is_null()
    }

    /// Returns a reference to the object owned by this UniquePtr if any,
    /// otherwise None.
    pub fn as_ref(&self) -> Option<&T> {
        unsafe { T::__get(self.repr).as_ref() }
    }

    /// Returns a mutable pinned reference to the object owned by this UniquePtr
    /// if any, otherwise None.
    pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
        unsafe {
            let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?;
            Some(Pin::new_unchecked(mut_reference))
        }
    }

    /// Returns a mutable pinned reference to the object owned by this
    /// UniquePtr.
    ///
    /// # Panics
    ///
    /// Panics if the UniquePtr holds a null pointer.
    pub fn pin_mut(&mut self) -> Pin<&mut T> {
        match self.as_mut() {
            Some(target) => target,
            None => panic!(
                "called pin_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }

    /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T.
    ///
    /// Matches the behavior of [std::unique_ptr\<T\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release).
    pub fn into_raw(self) -> *mut T {
        let ptr = unsafe { T::__release(self.repr) };
        mem::forget(self);
        ptr
    }

    /// Constructs a UniquePtr retaking ownership of a pointer previously
    /// obtained from `into_raw`.
    ///
    /// # Safety
    ///
    /// This function is unsafe because improper use may lead to memory
    /// problems. For example a double-free may occur if the function is called
    /// twice on the same raw pointer.
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        UniquePtr {
            repr: T::__raw(raw),
            ty: PhantomData,
        }
    }
}

unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}

impl<T> Drop for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    fn drop(&mut self) {
        unsafe { T::__drop(self.repr) }
    }
}

impl<T> Deref for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match self.as_ref() {
            Some(target) => target,
            None => panic!(
                "called deref on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> DerefMut for UniquePtr<T>
where
    T: UniquePtrTarget + Unpin,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self.as_mut() {
            Some(target) => Pin::into_inner(target),
            None => panic!(
                "called deref_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> Debug for UniquePtr<T>
where
    T: Debug + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Debug::fmt(value, formatter),
        }
    }
}

impl<T> Display for UniquePtr<T>
where
    T: Display + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Display::fmt(value, formatter),
        }
    }
}

/// Trait bound for types which may be used as the `T` inside of a
/// `UniquePtr<T>` in generic code.
///
/// This trait has no publicly callable or implementable methods. Implementing
/// it outside of the CXX codebase is not supported.
///
/// # Example
///
/// A bound `T: UniquePtrTarget` may be necessary when manipulating
/// [`UniquePtr`] in generic code.
///
/// ```
/// use cxx::memory::{UniquePtr, UniquePtrTarget};
/// use std::fmt::Display;
///
/// pub fn take_generic_ptr<T>(ptr: UniquePtr<T>)
/// where
///     T: UniquePtrTarget + Display,
/// {
///     println!("the unique_ptr points to: {}", *ptr);
/// }
/// ```
///
/// Writing the same generic function without a `UniquePtrTarget` trait bound
/// would not compile.
pub unsafe trait UniquePtrTarget {
    #[doc(hidden)]
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
    #[doc(hidden)]
    fn __null() -> *mut c_void;
    #[doc(hidden)]
    fn __new(value: Self) -> *mut c_void
    where
        Self: Sized,
    {
        // Opaque C types do not get this method because they can never exist by
        // value on the Rust side of the bridge.
        let _ = value;
        unreachable!()
    }
    #[doc(hidden)]
    unsafe fn __raw(raw: *mut Self) -> *mut c_void;
    #[doc(hidden)]
    unsafe fn __get(repr: *mut c_void) -> *const Self;
    #[doc(hidden)]
    unsafe fn __release(repr: *mut c_void) -> *mut Self;
    #[doc(hidden)]
    unsafe fn __drop(repr: *mut c_void);
}

extern "C" {
    #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
    fn unique_ptr_std_string_null(this: *mut *mut c_void);
    #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
    fn unique_ptr_std_string_raw(this: *mut *mut c_void, raw: *mut CxxString);
    #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
    fn unique_ptr_std_string_get(this: *const *mut c_void) -> *const CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
    fn unique_ptr_std_string_release(this: *mut *mut c_void) -> *mut CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
    fn unique_ptr_std_string_drop(this: *mut *mut c_void);
}

unsafe impl UniquePtrTarget for CxxString {
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("CxxString")
    }
    fn __null() -> *mut c_void {
        let mut repr = ptr::null_mut::<c_void>();
        unsafe {
            unique_ptr_std_string_null(&mut repr);
        }
        repr
    }
    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
        let mut repr = ptr::null_mut::<c_void>();
        unique_ptr_std_string_raw(&mut repr, raw);
        repr
    }
    unsafe fn __get(repr: *mut c_void) -> *const Self {
        unique_ptr_std_string_get(&repr)
    }
    unsafe fn __release(mut repr: *mut c_void) -> *mut Self {
        unique_ptr_std_string_release(&mut repr)
    }
    unsafe fn __drop(mut repr: *mut c_void) {
        unique_ptr_std_string_drop(&mut repr);
    }
}

unsafe impl<T> UniquePtrTarget for CxxVector<T>
where
    T: VectorElement,
{
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "CxxVector<{}>", display(T::__typename))
    }
    fn __null() -> *mut c_void {
        T::__unique_ptr_null()
    }
    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
        T::__unique_ptr_raw(raw)
    }
    unsafe fn __get(repr: *mut c_void) -> *const Self {
        T::__unique_ptr_get(repr)
    }
    unsafe fn __release(repr: *mut c_void) -> *mut Self {
        T::__unique_ptr_release(repr)
    }
    unsafe fn __drop(repr: *mut c_void) {
        T::__unique_ptr_drop(repr);
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "libc")]
pub extern crate libc;

#[macro_use]
mod macros;

#[macro_use]
pub mod coreopts;

#[cfg(feature = "fs")]
pub mod fs;
#[cfg(feature = "utf8")]
pub mod utf8;
#[cfg(feature = "encoding")]
pub mod encoding;
#[cfg(feature = "parse_time")]
pub mod parse_time;

#[cfg(all(unix, feature = "utmpx"))]
pub mod utmpx;
#[cfg(all(unix, feature = "utsname"))]
pub mod utsname;
#[cfg(all(unix, feature = "entries"))]
pub mod entries;
#[cfg(all(unix, feature = "process"))]
pub mod process;
#[cfg(all(unix, feature = "signals"))]
pub mod signals;

#[cfg(all(windows, feature = "wide"))]
pub mod wide;
<commit_msg>Turn off utmpx and signals for Fuchsia.<commit_after>#[cfg(feature = "libc")]
pub extern crate libc;

#[macro_use]
mod macros;

#[macro_use]
pub mod coreopts;

#[cfg(feature = "fs")]
pub mod fs;
#[cfg(feature = "utf8")]
pub mod utf8;
#[cfg(feature = "encoding")]
pub mod encoding;
#[cfg(feature = "parse_time")]
pub mod parse_time;

#[cfg(all(unix, not(target_os = "fuchsia"), feature = "utmpx"))]
pub mod utmpx;
#[cfg(all(unix, feature = "utsname"))]
pub mod utsname;
#[cfg(all(unix, feature = "entries"))]
pub mod entries;
#[cfg(all(unix, feature = "process"))]
pub mod process;
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
pub mod signals;

#[cfg(all(windows, feature = "wide"))]
pub mod wide;
<|endoftext|>


<commit_before>use std::env;
use std::io::stdin;
use std::str;
use std::sync::{Arc, RwLock};
use std::thread;

use pm;

pub fn get_devices() -> pm::Result<Vec<pm::DeviceInfo>> {
    try!(pm::initialize());
    let no = pm::count_devices();
    // use filter_map to discard None, and unwrap the Some(_)
    let devices = (0..no)
                      .filter_map(|i| pm::DeviceInfo::new(i))
                      .collect::<Vec<_>>();
    try!(pm::terminate());
    Ok(devices)
}

pub fn print_devices(devices: Vec<pm::DeviceInfo>) {
    println!("Id  Name                 Input? Output?");
    println!("=======================================");
    for d in devices.into_iter() {
        println!("{:<3} {:<20} {:<6} {:<6}",
                 d.device_id,
                 d.name,
                 d.is_input(),
                 d.is_output());
    }
}

pub fn die() {
    println!("Please supply a device number:");
    println!("");
    match get_devices() {
        Err(e) => println!("Error: {:?}", e),
        Ok(d) => print_devices(d),
    }
    // disable until set_exit_status is stable
    // env::set_exit_status(1);
}

pub fn get_arg<T: str::FromStr>(index: usize) -> Option<T> {
    let mut args = env::args();
    args.nth(index).and_then(|s| s.parse().ok())
}

pub struct QuitWatcher(Arc<RwLock<bool>>);

impl QuitWatcher {
    pub fn new() -> QuitWatcher {
        QuitWatcher(Arc::new(RwLock::new(false)))
    }

    pub fn start(&self) {
        let quit_lock = self.0.clone();
        thread::spawn(move || {
            println!("Press enter to quit");
            // read_line will block until enter is pressed
            stdin().read_line(&mut String::new()).ok().expect("Failed to read line");
            let mut quit = quit_lock.write().unwrap();
            *quit = true;
        });
    }

    pub fn is_running(&self) -> bool {
        let quit = self.0.read().unwrap();
        !*quit
    }
}
<commit_msg>Remove unused code<commit_after><|endoftext|>


<commit_before>use std::ops::Mul;
use std::fmt;

// Peano -----------------------------------------------------------------------
trait Peano {}
trait NonZero {}
trait NonNeg {}

struct Zero;
struct Succ<T: NonNeg>;

impl Peano for Zero {}
impl NonNeg for Zero {}

impl<T: NonNeg> Peano for Succ<T> {}
impl<T: NonNeg> NonNeg for Succ<T> {}

trait PInt: Peano + AddPeano + ToInt {}
impl PInt for Zero {}

impl<T: PInt + NonNeg> PInt for Succ<T>
    where Succ<T>: Peano + AddPeano + ToInt {}

trait AddPeano<RHS = Self> {
    type Output;
}

/// Adding things to zero (e.g. 0 + 3)
impl<RHS: Peano> AddPeano<RHS> for Zero {
    type Output = RHS;
}

/// Adding positive numbers (e.g. 1 + 2)
impl<T, RHS> AddPeano<Succ<RHS>> for Succ<T>
    where T: NonNeg + AddPeano<Succ<RHS>>, RHS: NonNeg {
        type Output = Succ<<T as AddPeano<Succ<RHS>>>::Output>;
    }

trait ToInt {
    fn to_int() -> i32;
}
impl ToInt for Zero {
    fn to_int() -> i32 { 0 }
}
impl<T: ToInt + NonNeg> ToInt for Succ<T> {
    fn to_int() -> i32 { 1 + <T as ToInt>::to_int() }
}

// Unit system -----------------------------------------------------------------------
struct Units<Meter: PInt>;

trait Dimension {}
impl<Meter: PInt> Dimension for Units<Meter> {}

trait AddDim<RHS = Self>: Dimension {
    type Output;
}

impl<Meter1, Meter2> AddDim<Units<Meter2>> for Units<Meter1>
    where Meter1: PInt + AddPeano<Meter2>, Meter2: PInt {
        type Output = Units<<Meter1 as AddPeano<Meter2>>::Output>;
    }

trait DimToString {
    fn to_string() -> String;
}

impl<Meter: ToInt> DimToString for Units<Meter> {
    fn to_string() -> String {
      let m_str = match <Meter as ToInt>::to_int() {
            0 => ("", "".to_string()),
            1 => ("m", "".to_string()),
            n => ("m^", (n/1).to_string())
          };
      format!("{}{}", m_str.0, m_str.1)
    }
}

// Dim -------------------------------------------------------------------------
struct Dim<T, V>(pub V);
impl<T, V: Copy> Copy for Dim<T, V> {}

impl<Tl, Vl, Tr, Vr> Mul<Dim<Tr,Vr>> for Dim<Tl, Vl>
    where Tl: AddDim<Tr>, Vl: Mul<Vr> {
        type Output = Dim<<Tl as AddDim<Tr>>::Output, <Vl as Mul<Vr>>::Output>;
        fn mul(self, rhs: Dim<Tr, Vr>) -> <Self as Mul<Dim<Tr, Vr>>>::Output {
            Dim( (self.0)*(rhs.0) )
        }
    }

impl<T, V> fmt::Display for Dim<T, V> where T: DimToString, V: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{} {}", self.0, <T as DimToString>::to_string())
    }
}

type One = Succ<Zero>;
type Two = Succ<One>;
type Three = Succ<Two>;
type Four = Succ<Three>;
type Five = Succ<Four>;

static m: Dim<Units<One>, f64> = Dim(1.0);

fn main() {
    let x = m;
    let y = x*x*x*x*x*x*x*x*x*x;
    println!("y: {}", y);
}
<commit_msg>Cleanup example<commit_after>use std::ops::Mul;
use std::fmt;

// Peano -----------------------------------------------------------------------
struct Zero;
struct Succ<N>;

trait AddPeano<N> {
    type Output;
}

/// Adding things to zero (e.g. 0 + 3)
impl<N> AddPeano<N> for Zero {
    type Output = N;
}

/// Adding positive numbers (e.g. 1 + 2)
impl<M, N> AddPeano<N> for Succ<M> where N: AddPeano<M> {
        type Output = Succ<<N as AddPeano<M>>::Output>;
}

trait ToInt {
    fn to_int() -> i32;
}
impl ToInt for Zero {
    fn to_int() -> i32 { 0 }
}
impl<N> ToInt for Succ<N> where N: ToInt {
    fn to_int() -> i32 { 1 + <N as ToInt>::to_int() }
}

// Unit system -----------------------------------------------------------------------
struct Units<Meter, Second>;

trait AddDim<R> {
    type Output;
}

impl<Ml, Sl, Mr, Sr> AddDim<Units<Mr, Sr>> for Units<Ml, Sl>
    where Ml: AddPeano<Mr>, Sl: AddPeano<Sr> {
        type Output = Units<<Ml as AddPeano<Mr>>::Output, <Sl as AddPeano<Sr>>::Output>;
}

trait DimToString {
    fn to_string() -> String;
}

impl<Meter, Second> DimToString for Units<Meter, Second> where Meter: ToInt, Second: ToInt {
    fn to_string() -> String {
      let m_str = match <Meter as ToInt>::to_int() {
            0 => ("", "".to_string()),
            1 => ("m", "".to_string()),
            n => ("m^", (n/1).to_string())
          };
      let s_str = match <Second as ToInt>::to_int() {
            0 => ("", "".to_string()),
            1 => ("s", "".to_string()),
            n => ("s^", (n/1).to_string())
          };
      format!("{}{}{}{}", m_str.0, m_str.1, s_str.0, s_str.1)
    }
}

// Dim -------------------------------------------------------------------------
struct Dim<U, V>(pub V);
impl<U, V> Copy for Dim<U, V> where V: Copy {}

impl<Ul, Vl, Ur, Vr> Mul<Dim<Ur,Vr>> for Dim<Ul, Vl>
    where Ul: AddDim<Ur>, Vl: Mul<Vr> {
        type Output = Dim<<Ul as AddDim<Ur>>::Output, <Vl as Mul<Vr>>::Output>;

        fn mul(self, rhs: Dim<Ur, Vr>) -> <Self as Mul<Dim<Ur, Vr>>>::Output {
            Dim( (self.0)*(rhs.0) )
        }
}

impl<U, V> fmt::Display for Dim<U, V> where U: DimToString, V: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{} {}", self.0, <U as DimToString>::to_string())
    }
}

type One = Succ<Zero>;
type Two = Succ<One>;
type Three = Succ<Two>;
type Four = Succ<Three>;
type Five = Succ<Four>;

static m: Dim<Units<One, Zero>, f64> = Dim(1.0);
static s: Dim<Units<Zero, One>, f64> = Dim(1.0);

fn main() {
    let x = m;
    let t = s;
    let a = x*x;
    println!("y: {}, t: {}", a, t);
}
<|endoftext|>


<commit_before>extern crate hal;
extern crate nalgebra as na;

use na::DMat;
use na::RowSlice;
use hal::{Model, Layer};
use hal::optimizer::{Optimizer, SGD};
use hal::error::HALError;
use hal::model::{Sequential};
use hal::layer::{Dense};
use hal::plot::plot_vec;

fn build_optimizer(name: &'static str) -> Result<Box<Optimizer>, HALError> {
  match name{
    "SGD" => Ok(Box::new(SGD::default())),
    _     => Err(HALError::UNKNOWN),
  }
}

fn generate_sin_wave(input_dims: usize, num_rows: usize) -> DMat<f32> {
  let mut waves = DMat::<f32>::new_zeros(num_rows, input_dims);
  let mut index: f32 = 0.0f32;
  let delta: f32 = 2.0*3.1415/(input_dims as f32);
  for r in 0..num_rows {
    for c in 0..input_dims {
      waves[(r, c)] = index.sin();
      index += delta;
    }
  }
  waves
}

fn main() {
  // First we need to parameterize our network
  let input_dims = 256;
  let hidden_dims = 128;
  let output_dims = 256;
  let num_train_samples = 1024;
  let iter = 5;
  let batch_size = 256;
  let optimizer_type = "SGD";

  // Now, let's build a model with an optimizer and a loss function
  let mut model = Box::new(Sequential::new(build_optimizer(optimizer_type).unwrap(), "mse"));

  // Let's add a few layers why don't we?
  model.add(Box::new(Dense::new(input_dims, hidden_dims, "tanh", "normal", "ones")));
  model.add(Box::new(Dense::new(hidden_dims, output_dims, "tanh", "normal", "ones")));

  // Get some nice information about our model
  model.info();

  // Test with learning to predict sin wave
  let mut data = generate_sin_wave(input_dims as usize, num_train_samples);
  let mut target = data.clone();
  //let cols = data.ncols();
  //println!("input row 0 : {:?}", data.row_slice(0, 0, cols-1));

  // iterate our model in Verbose mode (printing loss)
  let (loss, prediction) = model.fit(&mut data, &mut target, batch_size, iter, true, true);

  // plot our loss
  plot_vec(loss, "Loss vs. Iterations", 512, 512);
}
<commit_msg>increase batch size<commit_after>extern crate hal;
extern crate nalgebra as na;

use na::DMat;
use na::RowSlice;
use hal::{Model, Layer};
use hal::optimizer::{Optimizer, SGD};
use hal::error::HALError;
use hal::model::{Sequential};
use hal::layer::{Dense};
use hal::plot::plot_vec;

fn build_optimizer(name: &'static str) -> Result<Box<Optimizer>, HALError> {
  match name{
    "SGD" => Ok(Box::new(SGD::default())),
    _     => Err(HALError::UNKNOWN),
  }
}

fn generate_sin_wave(input_dims: usize, num_rows: usize) -> DMat<f32> {
  let mut waves = DMat::<f32>::new_zeros(num_rows, input_dims);
  let mut index: f32 = 0.0f32;
  let delta: f32 = 2.0*3.1415/(input_dims as f32);
  for r in 0..num_rows {
    for c in 0..input_dims {
      waves[(r, c)] = index.sin();
      index += delta;
    }
  }
  waves
}

fn main() {
  // First we need to parameterize our network
  let input_dims = 256;
  let hidden_dims = 128;
  let output_dims = 256;
  let num_train_samples = 1024;
  let iter = 1024;
  let batch_size = 256;
  let optimizer_type = "SGD";

  // Now, let's build a model with an optimizer and a loss function
  let mut model = Box::new(Sequential::new(build_optimizer(optimizer_type).unwrap(), "mse"));

  // Let's add a few layers why don't we?
  model.add(Box::new(Dense::new(input_dims, hidden_dims, "tanh", "normal", "ones")));
  model.add(Box::new(Dense::new(hidden_dims, output_dims, "tanh", "normal", "ones")));

  // Get some nice information about our model
  model.info();

  // Test with learning to predict sin wave
  let mut data = generate_sin_wave(input_dims as usize, num_train_samples);
  let mut target = data.clone();
  //let cols = data.ncols();
  //println!("input row 0 : {:?}", data.row_slice(0, 0, cols-1));

  // iterate our model in Verbose mode (printing loss)
  let (loss, prediction) = model.fit(&mut data, &mut target, batch_size, iter, true, true);

  // plot our loss
  plot_vec(loss, "Loss vs. Iterations", 512, 512);
}
<|endoftext|>


<commit_before>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{
    object::{Info, Installer},
    utils::{self, definitions::TargetTypeExt},
};
use failure::bail;
use pkg_schema::{definitions, objects};
use slog_scope::info;

impl Installer for objects::Ubifs {
    fn check_requirements(&self) -> Result<(), failure::Error> {
        info!("'ubifs' handle checking requirements");
        utils::fs::is_executable_in_path("ubiupdatevol")?;
        utils::fs::is_executable_in_path("ubinfo")?;

        if let definitions::TargetType::UBIVolume(_) = self.target.valid()? {
            return Ok(());
        }

        bail!("Unexpected target type, expected some device.")
    }

    fn install(&self, download_dir: &std::path::Path) -> Result<(), failure::Error> {
        info!("'ubifs' handler Install");

        let target = self.target.get_target()?;
        let source = download_dir.join(self.sha256sum());

        easy_process::run(&format!("ubiupdatevol {:?} {:?}", target, source))?;

        Ok(())
    }
}
<commit_msg>updatehub: ubifs installer test<commit_after>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{
    object::{Info, Installer},
    utils::{self, definitions::TargetTypeExt},
};
use failure::bail;
use pkg_schema::{definitions, objects};
use slog_scope::info;

impl Installer for objects::Ubifs {
    fn check_requirements(&self) -> Result<(), failure::Error> {
        info!("'ubifs' handle checking requirements");
        utils::fs::is_executable_in_path("ubiupdatevol")?;
        utils::fs::is_executable_in_path("ubinfo")?;

        if let definitions::TargetType::UBIVolume(_) = self.target.valid()? {
            return Ok(());
        }

        bail!("Unexpected target type, expected some device.")
    }

    fn install(&self, download_dir: &std::path::Path) -> Result<(), failure::Error> {
        info!("'ubifs' handler Install");

        let target = self.target.get_target()?;
        let source = download_dir.join(self.sha256sum());

        easy_process::run(&format!(
            "ubiupdatevol {} {}",
            target.display(),
            source.display()
        ))?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{
        object::installer::tests::create_echo_bins,
        utils::mtd::tests::{FakeUbi, MtdKind, SERIALIZE},
    };
    use pretty_assertions::assert_eq;
    use std::env;

    fn fake_ubifs_obj(name: &str) -> objects::Ubifs {
        objects::Ubifs {
            filename: "ubifs-filename".to_string(),
            size: 1024,
            sha256sum: "e3b0c44298fc1c149afb".to_string(),
            target: definitions::TargetType::UBIVolume(name.to_string()),

            compressed: true,
            required_uncompressed_size: 2048,
        }
    }

    #[test]
    fn check_requirements_with_missing_binaries() {
        let ubifs_obj = fake_ubifs_obj("home");

        env::set_var("PATH", "");
        assert!(ubifs_obj.check_requirements().is_err());

        env::set_var("PATH", "");
        let (_handle, _) = create_echo_bins(&["ubinfo"]).unwrap();
        assert!(ubifs_obj.check_requirements().is_err());

        env::set_var("PATH", "");
        let (_handle, _) = create_echo_bins(&["ubiupdatevol"]).unwrap();
        assert!(ubifs_obj.check_requirements().is_err());
    }

    #[test]
    #[ignore]
    fn install() {
        let _mtd_lock = SERIALIZE.lock();
        let _ubi = FakeUbi::new(&["home"], MtdKind::Nor).unwrap();
        let ubifs_obj = fake_ubifs_obj("home");
        let download_dir = tempfile::tempdir().unwrap();
        let target = ubifs_obj.target.get_target().unwrap();
        let source = download_dir.path().join(&ubifs_obj.sha256sum);

        let (_handle, calls) = create_echo_bins(&["ubiupdatevol"]).unwrap();

        ubifs_obj.check_requirements().unwrap();
        ubifs_obj.install(download_dir.path()).unwrap();

        let expected = format!("ubiupdatevol {} {}\n", target.display(), source.display());
        assert_eq!(std::fs::read_to_string(calls).unwrap(), expected);
    }
}
<|endoftext|>