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

/*!

Synchronous Timers

This module exposes the functionality to create timers, block the current task,
and create receivers which will receive notifications after a period of time.

*/

use comm::{Receiver, Sender, channel};
use io::{IoResult, IoError};
use kinds::Send;
use boxed::Box;
use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};

/// A synchronous timer object
///
/// Values of this type can be used to put the current task to sleep for a
/// period of time. Handles to this timer can also be created in the form of
/// receivers which will receive notifications over time.
///
/// # Example
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::Timer;
///
/// let mut timer = Timer::new().unwrap();
/// timer.sleep(10); // block the task for awhile
///
/// let timeout = timer.oneshot(10);
/// // do some work
/// timeout.recv(); // wait for the timeout to expire
///
/// let periodic = timer.periodic(10);
/// loop {
///     periodic.recv();
///     // this loop is only executed once every 10ms
/// }
/// # }
/// ```
///
/// If only sleeping is necessary, then a convenience API is provided through
/// the `io::timer` module.
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::timer;
///
/// // Put this task to sleep for 5 seconds
/// timer::sleep(5000);
/// # }
/// ```
pub struct Timer {
    obj: Box<RtioTimer + Send>,
}

struct TimerCallback { tx: Sender<()> }

/// Sleep the current task for `msecs` milliseconds.
pub fn sleep_ms(msecs: u64) {
    let timer = Timer::new();
    let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");

    timer.sleep_ms(msecs)
}

impl Timer {
    /// Creates a new timer which can be used to put the current task to sleep
    /// for a number of milliseconds, or to possibly create channels which will
    /// get notified after an amount of time has passed.
    pub fn new() -> IoResult<Timer> {
        LocalIo::maybe_raise(|io| {
            io.timer_init().map(|t| Timer { obj: t })
        }).map_err(IoError::from_rtio_error)
    }

    /// Blocks the current task for `msecs` milliseconds.
    ///
    /// Note that this function will cause any other receivers for this timer to
    /// be invalidated (the other end will be closed).
    pub fn sleep_ms(&mut self, msecs: u64) {
        self.obj.sleep(msecs);
    }

    /// Creates a oneshot receiver which will have a notification sent when
    /// `msecs` milliseconds has elapsed.
    ///
    /// This does *not* block the current task, but instead returns immediately.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    ///
    /// # Example
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// let mut timer = Timer::new().unwrap();
    /// let ten_milliseconds = timer.oneshot(10);
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 10 ms after the `oneshot` call
    /// ten_milliseconds.recv();
    /// ```
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// // Incorrect, method chaining-style:
    /// let mut five_ms = Timer::new().unwrap().oneshot(5);
    /// // The timer object was destroyed, so this will always fail:
    /// // five_ms.recv()
    /// ```
    pub fn oneshot_ms(&mut self, msecs: u64) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.oneshot(msecs, box TimerCallback { tx: tx });
        return rx
    }

    /// Creates a receiver which will have a continuous stream of notifications
    /// being sent every `msecs` milliseconds.
    ///
    /// This does *not* block the current task, but instead returns
    /// immediately. The first notification will not be received immediately,
    /// but rather after `msec` milliseconds have passed.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    ///
    /// # Example
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// let mut timer = Timer::new().unwrap();
    /// let ten_milliseconds = timer.periodic(10);
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 10 ms after the `periodic` call
    /// ten_milliseconds.recv();
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 20 ms after the `periodic` call (*not* 10ms after the
    /// // previous `recv`)
    /// ten_milliseconds.recv();
    /// ```
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// // Incorrect, method chaining-style.
    /// let mut five_ms = Timer::new().unwrap().periodic(5);
    /// // The timer object was destroyed, so this will always fail:
    /// // five_ms.recv()
    /// ```
    pub fn periodic_ms(&mut self, msecs: u64) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.period(msecs, box TimerCallback { tx: tx });
        return rx
    }
}

impl Callback for TimerCallback {
    fn call(&mut self) {
        let _ = self.tx.send_opt(());
    }
}

#[cfg(test)]
mod test {
    iotest!(fn test_io_timer_sleep_ms_simple() {
        let mut timer = Timer::new().unwrap();
        timer.sleep_ms(1);
    })

    iotest!(fn test_io_timer_sleep_oneshot_ms() {
        let mut timer = Timer::new().unwrap();
        timer.oneshot_ms(1).recv();
    })

    iotest!(fn test_io_timer_sleep_oneshot_ms_forget() {
        let mut timer = Timer::new().unwrap();
        timer.oneshot_ms(100000000000);
    })

    iotest!(fn oneshot_ms_twice() {
        let mut timer = Timer::new().unwrap();
        let rx1 = timer.oneshot_ms(10000);
        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert_eq!(rx1.recv_opt(), Err(()));
    })

    iotest!(fn test_io_timer_oneshot_ms_then_sleep() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.oneshot_ms(100000000000);
        timer.sleep_ms(1); // this should invalidate rx

        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn test_io_timer_sleep_periodic_ms() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.periodic_ms(1);
        rx.recv();
        rx.recv();
        rx.recv();
    })

    iotest!(fn test_io_timer_sleep_periodic_ms_forget() {
        let mut timer = Timer::new().unwrap();
        timer.periodic_ms(100000000000);
    })

    iotest!(fn test_io_timer_sleep_ms_standalone() {
        sleep_ms(1)
    })

    iotest!(fn oneshot_ms() {
        let mut timer = Timer::new().unwrap();

        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert!(rx.recv_opt().is_err());

        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert!(rx.recv_opt().is_err());
    })

    iotest!(fn override() {
        let mut timer = Timer::new().unwrap();
        let orx = timer.oneshot_ms(100);
        let prx = timer.periodic_ms(100);
        timer.sleep_ms(1);
        assert_eq!(orx.recv_opt(), Err(()));
        assert_eq!(prx.recv_opt(), Err(()));
        timer.oneshot_ms(1).recv();
    })

    iotest!(fn period_ms() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.periodic_ms(1);
        rx.recv();
        rx.recv();
        let rx2 = timer.periodic_ms(1);
        rx2.recv();
        rx2.recv();
    })

    iotest!(fn sleep_ms() {
        let mut timer = Timer::new().unwrap();
        timer.sleep_ms(1);
        timer.sleep_ms(1);
    })

    iotest!(fn oneshot_ms_fail() {
        let mut timer = Timer::new().unwrap();
        let _rx = timer.oneshot_ms(1);
        fail!();
    } #[should_fail])

    iotest!(fn period_ms_fail() {
        let mut timer = Timer::new().unwrap();
        let _rx = timer.periodic_ms(1);
        fail!();
    } #[should_fail])

    iotest!(fn normal_fail() {
        let _timer = Timer::new().unwrap();
        fail!();
    } #[should_fail])

    iotest!(fn closing_channel_during_drop_doesnt_kill_everything() {
        // see issue #10375
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        // when we drop the TimerWatcher we're going to destroy the channel,
        // which must wake up the task on the other end
    })

    iotest!(fn reset_doesnt_switch_tasks() {
        // similar test to the one above.
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        timer.oneshot_ms(1);
    })

    iotest!(fn reset_doesnt_switch_tasks2() {
        // similar test to the one above.
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        timer.sleep_ms(1);
    })

    iotest!(fn sender_goes_away_oneshot() {
        let rx = {
            let mut timer = Timer::new().unwrap();
            timer.oneshot_ms(1000)
        };
        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn sender_goes_away_period() {
        let rx = {
            let mut timer = Timer::new().unwrap();
            timer.periodic_ms(1000)
        };
        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn receiver_goes_away_oneshot() {
        let mut timer1 = Timer::new().unwrap();
        timer1.oneshot_ms(1);
        let mut timer2 = Timer::new().unwrap();
        // while sleeping, the previous timer should fire and not have its
        // callback do something terrible.
        timer2.sleep_ms(2);
    })

    iotest!(fn receiver_goes_away_period() {
        let mut timer1 = Timer::new().unwrap();
        timer1.periodic_ms(1);
        let mut timer2 = Timer::new().unwrap();
        // while sleeping, the previous timer should fire and not have its
        // callback do something terrible.
        timer2.sleep_ms(2);
    })
}
<commit_msg>std: Add sleep, oneshot and periodic timers, taking Duration<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Synchronous Timers

This module exposes the functionality to create timers, block the current task,
and create receivers which will receive notifications after a period of time.

*/

use comm::{Receiver, Sender, channel};
use time::Duration;
use io::{IoResult, IoError};
use kinds::Send;
use boxed::Box;
use num::{CheckedMul, CheckedAdd};
use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};

/// A synchronous timer object
///
/// Values of this type can be used to put the current task to sleep for a
/// period of time. Handles to this timer can also be created in the form of
/// receivers which will receive notifications over time.
///
/// # Example
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::Timer;
///
/// let mut timer = Timer::new().unwrap();
/// timer.sleep(10); // block the task for awhile
///
/// let timeout = timer.oneshot(10);
/// // do some work
/// timeout.recv(); // wait for the timeout to expire
///
/// let periodic = timer.periodic(10);
/// loop {
///     periodic.recv();
///     // this loop is only executed once every 10ms
/// }
/// # }
/// ```
///
/// If only sleeping is necessary, then a convenience API is provided through
/// the `io::timer` module.
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::timer;
///
/// // Put this task to sleep for 5 seconds
/// timer::sleep(5000);
/// # }
/// ```
pub struct Timer {
    obj: Box<RtioTimer + Send>,
}

struct TimerCallback { tx: Sender<()> }

#[allow(missing_doc)]
trait DurationExtension {
    fn in_ms(&self) -> u64;
}

impl DurationExtension for Duration {
    fn in_ms(&self) -> u64 {
        if self.ndays() < 0 { fail!("negative duration") }
        let nanos = self.nnanoseconds() as u64;
        let secs = self.nseconds() as u64;
        let days = self.ndays() as u64;
        let nanos_in_ms = nanos / 1000;
        let secs_in_ms = secs.checked_mul(&1000).expect("overflow");
        let ms_per_day = 24 * 60 * 60 * 1000; // hours/day * min/hour * sec/min * ms/sec
        let days_in_ms = days.checked_mul(&ms_per_day).expect("overflow");
        let result = nanos_in_ms;
        let result = result.checked_add(&secs_in_ms).expect("overflow");
        let result = result.checked_add(&(days_in_ms as u64)).expect("overflow");
        return result;
    }
}

/// Sleep the current task for the specified duration.
pub fn sleep(duration: Duration) {
    sleep_ms(duration.in_ms())
}

/// Sleep the current task for `msecs` milliseconds.
pub fn sleep_ms(msecs: u64) {
    let timer = Timer::new();
    let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");

    timer.sleep_ms(msecs)
}

impl Timer {
    /// Creates a new timer which can be used to put the current task to sleep
    /// for a number of milliseconds, or to possibly create channels which will
    /// get notified after an amount of time has passed.
    pub fn new() -> IoResult<Timer> {
        LocalIo::maybe_raise(|io| {
            io.timer_init().map(|t| Timer { obj: t })
        }).map_err(IoError::from_rtio_error)
    }

    /// Blocks the current task for the specified duration.
    ///
    /// Note that this function will cause any other receivers for this timer to
    /// be invalidated (the other end will be closed).
    pub fn sleep(&mut self, duration: Duration) {
        self.obj.sleep(duration.in_ms());
    }

    /// Blocks the current task for `msecs` milliseconds.
    ///
    /// Note that this function will cause any other receivers for this timer to
    /// be invalidated (the other end will be closed).
    pub fn sleep_ms(&mut self, msecs: u64) {
        self.obj.sleep(msecs);
    }

    /// Creates a oneshot receiver which will have a notification sent when
    /// the specified duration has elapsed.
    ///
    /// This does *not* block the current task, but instead returns immediately.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    pub fn oneshot(&mut self, duration: Duration) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.oneshot(duration.in_ms(), box TimerCallback { tx: tx });
        return rx
    }

    /// Creates a oneshot receiver which will have a notification sent when
    /// `msecs` milliseconds has elapsed.
    ///
    /// This does *not* block the current task, but instead returns immediately.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    ///
    /// # Example
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// let mut timer = Timer::new().unwrap();
    /// let ten_milliseconds = timer.oneshot(10);
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 10 ms after the `oneshot` call
    /// ten_milliseconds.recv();
    /// ```
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// // Incorrect, method chaining-style:
    /// let mut five_ms = Timer::new().unwrap().oneshot(5);
    /// // The timer object was destroyed, so this will always fail:
    /// // five_ms.recv()
    /// ```
    pub fn oneshot_ms(&mut self, msecs: u64) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.oneshot(msecs, box TimerCallback { tx: tx });
        return rx
    }

    /// Creates a receiver which will have a continuous stream of notifications
    /// being sent each time the specified duration has elapsed.
    ///
    /// This does *not* block the current task, but instead returns
    /// immediately. The first notification will not be received immediately,
    /// but rather after the first duration.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    pub fn periodic(&mut self, duration: Duration) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.period(duration.in_ms(), box TimerCallback { tx: tx });
        return rx
    }

    /// Creates a receiver which will have a continuous stream of notifications
    /// being sent every `msecs` milliseconds.
    ///
    /// This does *not* block the current task, but instead returns
    /// immediately. The first notification will not be received immediately,
    /// but rather after `msec` milliseconds have passed.
    ///
    /// Note that this invalidates any previous receiver which has been created
    /// by this timer, and that the returned receiver will be invalidated once
    /// the timer is destroyed (when it falls out of scope). In particular, if
    /// this is called in method-chaining style, the receiver will be
    /// invalidated at the end of that statement, and all `recv` calls will
    /// fail.
    ///
    /// # Example
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// let mut timer = Timer::new().unwrap();
    /// let ten_milliseconds = timer.periodic(10);
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 10 ms after the `periodic` call
    /// ten_milliseconds.recv();
    ///
    /// for _ in range(0u, 100) { /* do work */ }
    ///
    /// // blocks until 20 ms after the `periodic` call (*not* 10ms after the
    /// // previous `recv`)
    /// ten_milliseconds.recv();
    /// ```
    ///
    /// ```rust
    /// use std::io::Timer;
    ///
    /// // Incorrect, method chaining-style.
    /// let mut five_ms = Timer::new().unwrap().periodic(5);
    /// // The timer object was destroyed, so this will always fail:
    /// // five_ms.recv()
    /// ```
    pub fn periodic_ms(&mut self, msecs: u64) -> Receiver<()> {
        let (tx, rx) = channel();
        self.obj.period(msecs, box TimerCallback { tx: tx });
        return rx
    }
}

impl Callback for TimerCallback {
    fn call(&mut self) {
        let _ = self.tx.send_opt(());
    }
}

#[cfg(test)]
mod test {
    iotest!(fn test_io_timer_sleep_ms_simple() {
        let mut timer = Timer::new().unwrap();
        timer.sleep_ms(1);
    })

    iotest!(fn test_io_timer_sleep_oneshot_ms() {
        let mut timer = Timer::new().unwrap();
        timer.oneshot_ms(1).recv();
    })

    iotest!(fn test_io_timer_sleep_oneshot_ms_forget() {
        let mut timer = Timer::new().unwrap();
        timer.oneshot_ms(100000000000);
    })

    iotest!(fn oneshot_ms_twice() {
        let mut timer = Timer::new().unwrap();
        let rx1 = timer.oneshot_ms(10000);
        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert_eq!(rx1.recv_opt(), Err(()));
    })

    iotest!(fn test_io_timer_oneshot_ms_then_sleep() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.oneshot_ms(100000000000);
        timer.sleep_ms(1); // this should invalidate rx

        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn test_io_timer_sleep_periodic_ms() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.periodic_ms(1);
        rx.recv();
        rx.recv();
        rx.recv();
    })

    iotest!(fn test_io_timer_sleep_periodic_ms_forget() {
        let mut timer = Timer::new().unwrap();
        timer.periodic_ms(100000000000);
    })

    iotest!(fn test_io_timer_sleep_ms_standalone() {
        sleep_ms(1)
    })

    iotest!(fn oneshot_ms() {
        let mut timer = Timer::new().unwrap();

        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert!(rx.recv_opt().is_err());

        let rx = timer.oneshot_ms(1);
        rx.recv();
        assert!(rx.recv_opt().is_err());
    })

    iotest!(fn override() {
        let mut timer = Timer::new().unwrap();
        let orx = timer.oneshot_ms(100);
        let prx = timer.periodic_ms(100);
        timer.sleep_ms(1);
        assert_eq!(orx.recv_opt(), Err(()));
        assert_eq!(prx.recv_opt(), Err(()));
        timer.oneshot_ms(1).recv();
    })

    iotest!(fn period_ms() {
        let mut timer = Timer::new().unwrap();
        let rx = timer.periodic_ms(1);
        rx.recv();
        rx.recv();
        let rx2 = timer.periodic_ms(1);
        rx2.recv();
        rx2.recv();
    })

    iotest!(fn sleep_ms() {
        let mut timer = Timer::new().unwrap();
        timer.sleep_ms(1);
        timer.sleep_ms(1);
    })

    iotest!(fn oneshot_ms_fail() {
        let mut timer = Timer::new().unwrap();
        let _rx = timer.oneshot_ms(1);
        fail!();
    } #[should_fail])

    iotest!(fn period_ms_fail() {
        let mut timer = Timer::new().unwrap();
        let _rx = timer.periodic_ms(1);
        fail!();
    } #[should_fail])

    iotest!(fn normal_fail() {
        let _timer = Timer::new().unwrap();
        fail!();
    } #[should_fail])

    iotest!(fn closing_channel_during_drop_doesnt_kill_everything() {
        // see issue #10375
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        // when we drop the TimerWatcher we're going to destroy the channel,
        // which must wake up the task on the other end
    })

    iotest!(fn reset_doesnt_switch_tasks() {
        // similar test to the one above.
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        timer.oneshot_ms(1);
    })

    iotest!(fn reset_doesnt_switch_tasks2() {
        // similar test to the one above.
        let mut timer = Timer::new().unwrap();
        let timer_rx = timer.periodic_ms(1000);

        spawn(proc() {
            let _ = timer_rx.recv_opt();
        });

        timer.sleep_ms(1);
    })

    iotest!(fn sender_goes_away_oneshot() {
        let rx = {
            let mut timer = Timer::new().unwrap();
            timer.oneshot_ms(1000)
        };
        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn sender_goes_away_period() {
        let rx = {
            let mut timer = Timer::new().unwrap();
            timer.periodic_ms(1000)
        };
        assert_eq!(rx.recv_opt(), Err(()));
    })

    iotest!(fn receiver_goes_away_oneshot() {
        let mut timer1 = Timer::new().unwrap();
        timer1.oneshot_ms(1);
        let mut timer2 = Timer::new().unwrap();
        // while sleeping, the previous timer should fire and not have its
        // callback do something terrible.
        timer2.sleep_ms(2);
    })

    iotest!(fn receiver_goes_away_period() {
        let mut timer1 = Timer::new().unwrap();
        timer1.periodic_ms(1);
        let mut timer2 = Timer::new().unwrap();
        // while sleeping, the previous timer should fire and not have its
        // callback do something terrible.
        timer2.sleep_ms(2);
    })

    iotest!(fn test_io_timer_sleep_duration_simple() {
        use time::Duration;
        let mut timer = Timer::new().unwrap();
        timer.sleep(Duration::seconds(1));
    })

    iotest!(fn test_io_timer_sleep_oneshot_duration() {
        use time::Duration;
        let mut timer = Timer::new().unwrap();
        timer.oneshot(Duration::seconds(1)).recv();
    })

    iotest!(fn test_io_timer_sleep_periodic_duration() {
        use time::Duration;
        let mut timer = Timer::new().unwrap();
        let rx = timer.periodic(Duration::seconds(1));
        rx.recv();
        rx.recv();
        rx.recv();
    })

}
<|endoftext|>


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

use option::{Option, Some, None};
use rt::sched::Scheduler;
use rt::task::Task;
use rt::local_ptr;
use rt::rtio::{EventLoop, IoFactoryObject};
//use borrow::to_uint;

pub trait Local {
    fn put(value: ~Self);
    fn take() -> ~Self;
    fn exists() -> bool;
    fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
    unsafe fn unsafe_borrow() -> *mut Self;
    unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
}

impl Local for Scheduler {
    fn put(value: ~Scheduler) { unsafe { local_ptr::put(value) }}
    fn take() -> ~Scheduler { unsafe { local_ptr::take() } }
    fn exists() -> bool { local_ptr::exists() }
    fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
        let mut res: Option<T> = None;
        let res_ptr: *mut Option<T> = &mut res;
        unsafe {
            do local_ptr::borrow |sched| {
//                rtdebug!("successfully unsafe borrowed sched pointer");
                let result = f(sched);
                *res_ptr = Some(result);
            }
        }
        match res {
            Some(r) => { r }
            None => rtabort!("function failed!")
        }
    }
    unsafe fn unsafe_borrow() -> *mut Scheduler { local_ptr::unsafe_borrow() }
    unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> { rtabort!("unimpl") }
}

impl Local for Task {
    fn put(_value: ~Task) { rtabort!("unimpl") }
    fn take() -> ~Task { rtabort!("unimpl") }
    fn exists() -> bool { rtabort!("unimpl") }
    fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
        do Local::borrow::<Scheduler, T> |sched| {
//            rtdebug!("sched about to grab current_task");
            match sched.current_task {
                Some(~ref mut task) => {
//                    rtdebug!("current task pointer: %x", to_uint(task));
//                    rtdebug!("current task heap pointer: %x", to_uint(&task.heap));
                    f(task)
                }
                None => {
                    rtabort!("no scheduler")
                }
            }
        }
    }
    unsafe fn unsafe_borrow() -> *mut Task {
        match (*Local::unsafe_borrow::<Scheduler>()).current_task {
            Some(~ref mut task) => {
                let s: *mut Task = &mut *task;
                return s;
            }
            None => {
                // Don't fail. Infinite recursion
                rtabort!("no scheduler")
            }
        }
    }
    unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
        if Local::exists::<Scheduler>() {
            Some(Local::unsafe_borrow())
        } else {
            None
        }
    }
}

// XXX: This formulation won't work once ~IoFactoryObject is a real trait pointer
impl Local for IoFactoryObject {
    fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
    fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
    fn exists() -> bool { rtabort!("unimpl") }
    fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
    unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
        let sched = Local::unsafe_borrow::<Scheduler>();
        let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
        return io;
    }
    unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") }
}

#[cfg(test)]
mod test {
    use rt::test::*;
    use rt::sched::Scheduler;
    use super::*;

    #[test]
    fn thread_local_scheduler_smoke_test() {
        let scheduler = ~new_test_uv_sched();
        Local::put(scheduler);
        let _scheduler: ~Scheduler = Local::take();
    }

    #[test]
    fn thread_local_scheduler_two_instances() {
        let scheduler = ~new_test_uv_sched();
        Local::put(scheduler);
        let _scheduler: ~Scheduler = Local::take();
        let scheduler = ~new_test_uv_sched();
        Local::put(scheduler);
        let _scheduler: ~Scheduler = Local::take();
    }

    #[test]
    fn borrow_smoke_test() {
        let scheduler = ~new_test_uv_sched();
        Local::put(scheduler);
        unsafe {
            let _scheduler: *mut Scheduler = Local::unsafe_borrow();
        }
        let _scheduler: ~Scheduler = Local::take();
    }

    #[test]
    fn borrow_with_return() {
        let scheduler = ~new_test_uv_sched();
        Local::put(scheduler);
        let res = do Local::borrow::<Scheduler,bool> |_sched| {
            true
        };
        assert!(res)
        let _scheduler: ~Scheduler = Local::take();
    }

}
<commit_msg>std::rt: Do local tests in a bare thread to not interfere with the scheduler<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use option::{Option, Some, None};
use rt::sched::Scheduler;
use rt::task::Task;
use rt::local_ptr;
use rt::rtio::{EventLoop, IoFactoryObject};
//use borrow::to_uint;

pub trait Local {
    fn put(value: ~Self);
    fn take() -> ~Self;
    fn exists() -> bool;
    fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
    unsafe fn unsafe_borrow() -> *mut Self;
    unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
}

impl Local for Scheduler {
    fn put(value: ~Scheduler) { unsafe { local_ptr::put(value) }}
    fn take() -> ~Scheduler { unsafe { local_ptr::take() } }
    fn exists() -> bool { local_ptr::exists() }
    fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
        let mut res: Option<T> = None;
        let res_ptr: *mut Option<T> = &mut res;
        unsafe {
            do local_ptr::borrow |sched| {
//                rtdebug!("successfully unsafe borrowed sched pointer");
                let result = f(sched);
                *res_ptr = Some(result);
            }
        }
        match res {
            Some(r) => { r }
            None => rtabort!("function failed!")
        }
    }
    unsafe fn unsafe_borrow() -> *mut Scheduler { local_ptr::unsafe_borrow() }
    unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> { rtabort!("unimpl") }
}

impl Local for Task {
    fn put(_value: ~Task) { rtabort!("unimpl") }
    fn take() -> ~Task { rtabort!("unimpl") }
    fn exists() -> bool { rtabort!("unimpl") }
    fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
        do Local::borrow::<Scheduler, T> |sched| {
//            rtdebug!("sched about to grab current_task");
            match sched.current_task {
                Some(~ref mut task) => {
//                    rtdebug!("current task pointer: %x", to_uint(task));
//                    rtdebug!("current task heap pointer: %x", to_uint(&task.heap));
                    f(task)
                }
                None => {
                    rtabort!("no scheduler")
                }
            }
        }
    }
    unsafe fn unsafe_borrow() -> *mut Task {
        match (*Local::unsafe_borrow::<Scheduler>()).current_task {
            Some(~ref mut task) => {
                let s: *mut Task = &mut *task;
                return s;
            }
            None => {
                // Don't fail. Infinite recursion
                rtabort!("no scheduler")
            }
        }
    }
    unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
        if Local::exists::<Scheduler>() {
            Some(Local::unsafe_borrow())
        } else {
            None
        }
    }
}

// XXX: This formulation won't work once ~IoFactoryObject is a real trait pointer
impl Local for IoFactoryObject {
    fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
    fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
    fn exists() -> bool { rtabort!("unimpl") }
    fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
    unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
        let sched = Local::unsafe_borrow::<Scheduler>();
        let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
        return io;
    }
    unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") }
}

#[cfg(test)]
mod test {
    use unstable::run_in_bare_thread;
    use rt::test::*;
    use rt::sched::Scheduler;
    use super::*;

    #[test]
    fn thread_local_scheduler_smoke_test() {
        do run_in_bare_thread {
            let scheduler = ~new_test_uv_sched();
            Local::put(scheduler);
            let _scheduler: ~Scheduler = Local::take();
        }
    }

    #[test]
    fn thread_local_scheduler_two_instances() {
        do run_in_bare_thread {
            let scheduler = ~new_test_uv_sched();
            Local::put(scheduler);
            let _scheduler: ~Scheduler = Local::take();
            let scheduler = ~new_test_uv_sched();
            Local::put(scheduler);
            let _scheduler: ~Scheduler = Local::take();
        }
    }

    #[test]
    fn borrow_smoke_test() {
        do run_in_bare_thread {
            let scheduler = ~new_test_uv_sched();
            Local::put(scheduler);
            unsafe {
                let _scheduler: *mut Scheduler = Local::unsafe_borrow();
            }
            let _scheduler: ~Scheduler = Local::take();
        }
    }

    #[test]
    fn borrow_with_return() {
        do run_in_bare_thread {
            let scheduler = ~new_test_uv_sched();
            Local::put(scheduler);
            let res = do Local::borrow::<Scheduler,bool> |_sched| {
                true
            };
            assert!(res);
            let _scheduler: ~Scheduler = Local::take();
        }
    }

}
<|endoftext|>


<commit_before>extern crate libc;
use libc::{mode_t, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IRUSR, S_IWUSR};

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

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

fn parse_symbolic(mut fperm: mode_t, mut mode: &str) -> Result<mode_t, String> {
    let (mask, pos) = parse_levels(mode);
    if pos == mode.len() {
        return Err("invalid mode".to_owned());
    }
    mode = &mode[pos..];
    while mode.len() > 0 {
        let (op, pos) = try!(parse_op(mode, None));
        mode = &mode[pos..];
        let (srwx, pos) = parse_change(mode, fperm);
        mode = &mode[pos..];
        match op {
            '+' => fperm |= srwx & mask,
            '-' => fperm &= !(srwx & mask),
            '=' => fperm = (fperm & !mask) | (srwx & mask),
            _ => unreachable!(),
        }
    }
    Ok(fperm)
}

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

fn parse_numeric(fperm: mode_t, mut mode: &str) -> Result<mode_t, String> {
    let (op, pos) = try!(parse_op(mode, Some('=')));
    mode = mode[pos..].trim_left_matches('0');
    match mode_t::from_str_radix(mode, 8) {
        Ok(change) => {
            let after = match op {
                '+' => fperm | change,
                '-' => fperm & !change,
                '=' => change,
                _ => unreachable!(),
            };
            if after > 0o7777 {
                return Err("invalid mode".to_owned());
            }
            Ok(after)
        }
        Err(_) => Err("invalid mode".to_owned()),
    }
}
pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
    let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    if let Some(mode) = mode {
        let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        let result = if mode.contains(arr) {
            parse_numeric(fperm, mode.as_str())
        } else {
            parse_symbolic(fperm, mode.as_str())
        };
        result
    } else {
        Ok(fperm)
    }
}

#[test]
fn symbolic_modes() {
    assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("+x".to_owned())).unwrap(), 0o777);
    assert_eq!(parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
    assert_eq!(parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
}

#[test]
fn numeric_modes() {
    assert_eq!(parse_mode(Some("644".to_owned())).unwrap(), 0o644);
    assert_eq!(parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
    assert_eq!(parse_mode(None).unwrap(), 0o666);
}
<commit_msg>mknod: use mode parsing in uucore<commit_after>extern crate libc;
use libc::{mode_t, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IRUSR, S_IWUSR};

use uucore::mode;

pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
    let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    if let Some(mode) = mode {
        let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        let result = if mode.contains(arr) {
            mode::parse_numeric(fperm, mode.as_str())
        } else {
            mode::parse_symbolic(fperm, mode.as_str(), true)
        };
        result.map(|mode| mode as mode_t)
    } else {
        Ok(fperm)
    }
}

#[test]
fn symbolic_modes() {
    assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("+x".to_owned())).unwrap(), 0o777);
    assert_eq!(parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
    assert_eq!(parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
}

#[test]
fn numeric_modes() {
    assert_eq!(parse_mode(Some("644".to_owned())).unwrap(), 0o644);
    assert_eq!(parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
    assert_eq!(parse_mode(None).unwrap(), 0o666);
}
<|endoftext|>


<commit_before>//! Utilities for parsing and formatting RFC 3339 timestamps.
//!
//! The [`Timestamp`] newtype wraps `chrono::DateTime<Utc>` or `time::OffsetDateTime` if the `time`
//! feature is enabled.
//!
//! # Formatting
//! ```
//! # use serenity::model::id::GuildId;
//! # use serenity::model::Timestamp;
//! #
//! let timestamp: Timestamp = GuildId(175928847299117063).created_at();
//! assert_eq!(timestamp.unix_timestamp(), 1462015105);
//! assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
//! ```
//!
//! # Parsing RFC 3339 string
//! ```
//! # use serenity::model::Timestamp;
//! #
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
//!
//! let timestamp: Timestamp = "2016-04-30T11:18:25Z".parse().unwrap();
//! let timestamp: Timestamp = "2016-04-30T11:18:25+00:00".parse().unwrap();
//! let timestamp: Timestamp = "2016-04-30T11:18:25.796Z".parse().unwrap();
//!
//! assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
//! assert!(Timestamp::parse("2016-04-30T11:18").is_err());
//! ```

use std::fmt;
use std::ops::Deref;
use std::str::FromStr;

#[cfg(not(feature = "time"))]
use chrono::{DateTime, TimeZone, Utc};
use serde::{Deserialize, Serialize};
#[cfg(feature = "time")]
use time::format_description::well_known::Rfc3339;
#[cfg(feature = "time")]
use time::serde::rfc3339;
#[cfg(feature = "time")]
use time::{Duration, OffsetDateTime};

/// Discord's epoch starts at "2015-01-01T00:00:00+00:00"
const DISCORD_EPOCH: u64 = 1_420_070_400_000;

/// Representation of a Unix timestamp.
///
/// The struct implements the `std::fmt::Display` trait to format the underlying type as
/// an RFC 3339 date and string such as `2016-04-30T11:18:25.796Z`.
///
/// ```
/// # use serenity::model::id::GuildId;
/// # use serenity::model::Timestamp;
/// #
/// let timestamp: Timestamp = GuildId(175928847299117063).created_at();
/// assert_eq!(timestamp.unix_timestamp(), 1462015105);
/// assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
/// ```
#[cfg(not(feature = "time"))]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct Timestamp(DateTime<Utc>);

/// Representation of a Unix timestamp.
///
/// The struct implements the `std::fmt::Display` trait to format the underlying type as
/// an RFC 3339 date and string such as `2016-04-30T11:18:25.796Z`.
///
/// ```
/// # use serenity::model::id::GuildId;
/// # use serenity::model::Timestamp;
/// #
/// let timestamp: Timestamp = GuildId(175928847299117063).created_at();
/// assert_eq!(timestamp.unix_timestamp(), 1462015105);
/// assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
/// ```
#[cfg(feature = "time")]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct Timestamp(#[serde(with = "rfc3339")] OffsetDateTime);

#[cfg(feature = "time")]
impl Timestamp {
    pub(crate) fn from_discord_id(id: u64) -> Timestamp {
        let ns = Duration::milliseconds(((id >> 22) + DISCORD_EPOCH) as i64).whole_nanoseconds();
        // This can't fail because of the bit shifting
        // `(u64::MAX >> 22) + DISCORD_EPOCH` = 5818116911103 = "Wed May 15 2154 07:35:11 GMT+0000"
        Self(OffsetDateTime::from_unix_timestamp_nanos(ns).expect("can't fail"))
    }

    /// Create a new `Timestamp` with the current date and time in UTC.
    pub fn now() -> Self {
        Self(OffsetDateTime::now_utc())
    }

    /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC
    pub fn unix_timestamp(&self) -> i64 {
        self.0.unix_timestamp()
    }

    /// Parse a timestamp from an RFC 3339 date and time string.
    ///
    /// # Examples
    /// ```
    /// # use serenity::model::Timestamp;
    /// #
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
    ///
    /// assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
    /// assert!(Timestamp::parse("2016-04-30T11:18").is_err());
    /// ```
    ///
    /// # Errors
    ///
    /// Returns `Err` if the string is not a valid RFC 3339 date and time string.
    pub fn parse(input: &str) -> Result<Timestamp, ParseError> {
        OffsetDateTime::parse(input, &Rfc3339).map(Self).map_err(ParseError)
    }
}

#[cfg(not(feature = "time"))]
impl Timestamp {
    pub(crate) fn from_discord_id(id: u64) -> Timestamp {
        Self(Utc.timestamp_millis(((id >> 22) + DISCORD_EPOCH) as i64))
    }

    /// Create a new `Timestamp` with the current date and time in UTC.
    pub fn now() -> Self {
        Self(Utc::now())
    }

    /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC
    pub fn unix_timestamp(&self) -> i64 {
        self.0.timestamp()
    }

    /// Parse a timestamp from an RFC 3339 date and time string.
    ///
    /// # Examples
    /// ```
    /// # use serenity::model::Timestamp;
    /// #
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
    ///
    /// assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
    /// assert!(Timestamp::parse("2016-04-30T11:18").is_err());
    /// ```
    ///
    /// # Errors
    ///
    /// Returns `Err` if the string is not a valid RFC 3339 date and time string.
    pub fn parse(input: &str) -> Result<Timestamp, ParseError> {
        DateTime::parse_from_rfc3339(input).map(|d| Self(d.with_timezone(&Utc))).map_err(ParseError)
    }
}

#[cfg(not(feature = "time"))]
use chrono::ParseError as InnerError;
#[cfg(feature = "time")]
use time::error::Parse as InnerError;

/// Signifies the failure to parse the `Timestamp` from an RFC 3339 string.
#[derive(Debug)]
pub struct ParseError(InnerError);

impl std::error::Error for ParseError {}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

#[cfg(feature = "time")]
impl fmt::Display for Timestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = self.0.format(&Rfc3339).map_err(|_| fmt::Error)?;
        f.write_str(&s)
    }
}

#[cfg(not(feature = "time"))]
impl fmt::Display for Timestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use chrono::SecondsFormat;
        let s = self.0.to_rfc3339_opts(SecondsFormat::Millis, true);
        f.write_str(&s)
    }
}

#[cfg(not(feature = "time"))]
impl Deref for Timestamp {
    type Target = DateTime<Utc>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[cfg(feature = "time")]
impl Deref for Timestamp {
    type Target = OffsetDateTime;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl FromStr for Timestamp {
    type Err = ParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Timestamp::parse(s)
    }
}

impl From<String> for Timestamp {
    /// Parses an RFC 3339 date and time string such as `2016-04-30T11:18:25.796Z`.
    ///
    /// Panics on invalid value.
    fn from(s: String) -> Self {
        #[allow(clippy::unwrap_used)]
        Timestamp::parse(&s).unwrap()
    }
}

impl<'a> From<&'a str> for Timestamp {
    /// Parses an RFC 3339 date and time string such as `2016-04-30T11:18:25.796Z`.
    ///
    /// Panics on invalid value.
    fn from(s: &'a str) -> Self {
        #[allow(clippy::unwrap_used)]
        Timestamp::parse(s).unwrap()
    }
}

impl From<&Timestamp> for Timestamp {
    fn from(ts: &Timestamp) -> Self {
        *ts
    }
}

#[cfg(not(feature = "time"))]
impl<Tz: TimeZone> From<DateTime<Tz>> for Timestamp {
    fn from(dt: DateTime<Tz>) -> Self {
        Self(dt.with_timezone(&Utc))
    }
}

#[cfg(feature = "time")]
impl From<OffsetDateTime> for Timestamp {
    fn from(dt: OffsetDateTime) -> Self {
        Self(dt)
    }
}
<commit_msg>Add method to create `model::Timestamp` from a UNIX timestamp (#1790)<commit_after>//! Utilities for parsing and formatting RFC 3339 timestamps.
//!
//! The [`Timestamp`] newtype wraps `chrono::DateTime<Utc>` or `time::OffsetDateTime` if the `time`
//! feature is enabled.
//!
//! # Formatting
//! ```
//! # use serenity::model::id::GuildId;
//! # use serenity::model::Timestamp;
//! #
//! let timestamp: Timestamp = GuildId(175928847299117063).created_at();
//! assert_eq!(timestamp.unix_timestamp(), 1462015105);
//! assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
//! ```
//!
//! # Parsing RFC 3339 string
//! ```
//! # use serenity::model::Timestamp;
//! #
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
//! let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
//!
//! let timestamp: Timestamp = "2016-04-30T11:18:25Z".parse().unwrap();
//! let timestamp: Timestamp = "2016-04-30T11:18:25+00:00".parse().unwrap();
//! let timestamp: Timestamp = "2016-04-30T11:18:25.796Z".parse().unwrap();
//!
//! assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
//! assert!(Timestamp::parse("2016-04-30T11:18").is_err());
//! ```

use std::fmt;
use std::ops::Deref;
use std::str::FromStr;

#[cfg(not(feature = "time"))]
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
use serde::{Deserialize, Serialize};
#[cfg(feature = "time")]
use time::format_description::well_known::Rfc3339;
#[cfg(feature = "time")]
use time::serde::rfc3339;
#[cfg(feature = "time")]
use time::{Duration, OffsetDateTime};

/// Discord's epoch starts at "2015-01-01T00:00:00+00:00"
const DISCORD_EPOCH: u64 = 1_420_070_400_000;

/// Representation of a Unix timestamp.
///
/// The struct implements the `std::fmt::Display` trait to format the underlying type as
/// an RFC 3339 date and string such as `2016-04-30T11:18:25.796Z`.
///
/// ```
/// # use serenity::model::id::GuildId;
/// # use serenity::model::Timestamp;
/// #
/// let timestamp: Timestamp = GuildId(175928847299117063).created_at();
/// assert_eq!(timestamp.unix_timestamp(), 1462015105);
/// assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
/// ```
#[cfg(not(feature = "time"))]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct Timestamp(DateTime<Utc>);

/// Representation of a Unix timestamp.
///
/// The struct implements the `std::fmt::Display` trait to format the underlying type as
/// an RFC 3339 date and string such as `2016-04-30T11:18:25.796Z`.
///
/// ```
/// # use serenity::model::id::GuildId;
/// # use serenity::model::Timestamp;
/// #
/// let timestamp: Timestamp = GuildId(175928847299117063).created_at();
/// assert_eq!(timestamp.unix_timestamp(), 1462015105);
/// assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.796Z");
/// ```
#[cfg(feature = "time")]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct Timestamp(#[serde(with = "rfc3339")] OffsetDateTime);

#[cfg(feature = "time")]
impl Timestamp {
    pub(crate) fn from_discord_id(id: u64) -> Timestamp {
        let ns = Duration::milliseconds(((id >> 22) + DISCORD_EPOCH) as i64).whole_nanoseconds();
        // This can't fail because of the bit shifting
        // `(u64::MAX >> 22) + DISCORD_EPOCH` = 5818116911103 = "Wed May 15 2154 07:35:11 GMT+0000"
        Self(OffsetDateTime::from_unix_timestamp_nanos(ns).expect("can't fail"))
    }

    /// Create a new `Timestamp` with the current date and time in UTC.
    pub fn now() -> Self {
        Self(OffsetDateTime::now_utc())
    }

    /// Create a new `Timestamp` from a UNIX timestamp.
    ///
    /// Returns `Err` if the value is invalid. The valid range of the value may vary depending on
    /// the feature flags enabled (`time` with `large-dates`).
    pub fn from_unix_timestamp(secs: i64) -> Result<Self, InvalidTimestamp> {
        let dt = OffsetDateTime::from_unix_timestamp(secs).map_err(|_| InvalidTimestamp)?;
        Ok(Self(dt))
    }

    /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC
    pub fn unix_timestamp(&self) -> i64 {
        self.0.unix_timestamp()
    }

    /// Parse a timestamp from an RFC 3339 date and time string.
    ///
    /// # Examples
    /// ```
    /// # use serenity::model::Timestamp;
    /// #
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
    ///
    /// assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
    /// assert!(Timestamp::parse("2016-04-30T11:18").is_err());
    /// ```
    ///
    /// # Errors
    ///
    /// Returns `Err` if the string is not a valid RFC 3339 date and time string.
    pub fn parse(input: &str) -> Result<Timestamp, ParseError> {
        OffsetDateTime::parse(input, &Rfc3339).map(Self).map_err(ParseError)
    }
}

#[cfg(not(feature = "time"))]
impl Timestamp {
    pub(crate) fn from_discord_id(id: u64) -> Timestamp {
        Self(Utc.timestamp_millis(((id >> 22) + DISCORD_EPOCH) as i64))
    }

    /// Create a new `Timestamp` with the current date and time in UTC.
    pub fn now() -> Self {
        Self(Utc::now())
    }

    /// Create a new `Timestamp` from a UNIX timestamp.
    ///
    /// # Errors
    ///
    /// Returns `Err` if the value is invalid.
    pub fn from_unix_timestamp(secs: i64) -> Result<Self, InvalidTimestamp> {
        let dt = NaiveDateTime::from_timestamp_opt(secs, 0).ok_or(InvalidTimestamp)?;
        Ok(Self(DateTime::from_utc(dt, Utc)))
    }

    /// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC
    pub fn unix_timestamp(&self) -> i64 {
        self.0.timestamp()
    }

    /// Parse a timestamp from an RFC 3339 date and time string.
    ///
    /// # Examples
    /// ```
    /// # use serenity::model::Timestamp;
    /// #
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25Z").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25+00:00").unwrap();
    /// let timestamp = Timestamp::parse("2016-04-30T11:18:25.796Z").unwrap();
    ///
    /// assert!(Timestamp::parse("2016-04-30T11:18:25").is_err());
    /// assert!(Timestamp::parse("2016-04-30T11:18").is_err());
    /// ```
    ///
    /// # Errors
    ///
    /// Returns `Err` if the string is not a valid RFC 3339 date and time string.
    pub fn parse(input: &str) -> Result<Timestamp, ParseError> {
        DateTime::parse_from_rfc3339(input).map(|d| Self(d.with_timezone(&Utc))).map_err(ParseError)
    }
}

#[derive(Debug)]
pub struct InvalidTimestamp;

impl std::error::Error for InvalidTimestamp {}

impl fmt::Display for InvalidTimestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("invalid UNIX timestamp value")
    }
}

#[cfg(not(feature = "time"))]
use chrono::ParseError as InnerError;
#[cfg(feature = "time")]
use time::error::Parse as InnerError;

/// Signifies the failure to parse the `Timestamp` from an RFC 3339 string.
#[derive(Debug)]
pub struct ParseError(InnerError);

impl std::error::Error for ParseError {}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

#[cfg(feature = "time")]
impl fmt::Display for Timestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = self.0.format(&Rfc3339).map_err(|_| fmt::Error)?;
        f.write_str(&s)
    }
}

#[cfg(not(feature = "time"))]
impl fmt::Display for Timestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use chrono::SecondsFormat;
        let s = self.0.to_rfc3339_opts(SecondsFormat::Millis, true);
        f.write_str(&s)
    }
}

#[cfg(not(feature = "time"))]
impl Deref for Timestamp {
    type Target = DateTime<Utc>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[cfg(feature = "time")]
impl Deref for Timestamp {
    type Target = OffsetDateTime;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl FromStr for Timestamp {
    type Err = ParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Timestamp::parse(s)
    }
}

impl From<String> for Timestamp {
    /// Parses an RFC 3339 date and time string such as `2016-04-30T11:18:25.796Z`.
    ///
    /// Panics on invalid value.
    fn from(s: String) -> Self {
        #[allow(clippy::unwrap_used)]
        Timestamp::parse(&s).unwrap()
    }
}

impl<'a> From<&'a str> for Timestamp {
    /// Parses an RFC 3339 date and time string such as `2016-04-30T11:18:25.796Z`.
    ///
    /// Panics on invalid value.
    fn from(s: &'a str) -> Self {
        #[allow(clippy::unwrap_used)]
        Timestamp::parse(s).unwrap()
    }
}

impl From<&Timestamp> for Timestamp {
    fn from(ts: &Timestamp) -> Self {
        *ts
    }
}

#[cfg(not(feature = "time"))]
impl<Tz: TimeZone> From<DateTime<Tz>> for Timestamp {
    fn from(dt: DateTime<Tz>) -> Self {
        Self(dt.with_timezone(&Utc))
    }
}

#[cfg(feature = "time")]
impl From<OffsetDateTime> for Timestamp {
    fn from(dt: OffsetDateTime) -> Self {
        Self(dt)
    }
}

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

    #[test]
    fn from_unix_timestamp() {
        let timestamp = Timestamp::from_unix_timestamp(1462015105).unwrap();
        assert_eq!(timestamp.unix_timestamp(), 1462015105);
        #[cfg(not(feature = "time"))]
        assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25.000Z");
        #[cfg(feature = "time")]
        assert_eq!(timestamp.to_string(), "2016-04-30T11:18:25Z");
    }
}
<|endoftext|>


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

//! Bit fiddling on positive IEEE 754 floats. Negative numbers aren't and needn't be handled.
//! Normal floating point numbers have a canonical representation as (frac, exp) such that the
//! value is 2^exp * (1 + sum(frac[N-i] / 2^i)) where N is the number of bits. Subnormals are
//! slightly different and weird, but the same principle applies.
//!
//! Here, however, we represent them as (sig, k) with f positive, such that the value is f * 2^e.
//! Besides making the "hidden bit" explicit, this changes the exponent by the so-called
//! mantissa shift.
//!
//! Put another way, normally floats are written as (1) but here they are written as (2):
//!
//! 1. `1.101100...11 * 2^m`
//! 2. `1101100...11 * 2^n`
//!
//! We call (1) the **fractional representation** and (2) the **integral representation**.
//!
//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
//! That algorithm needs only next_float() which does handle subnormals and zeros.
use prelude::v1::*;
use u32;
use cmp::Ordering::{Less, Equal, Greater};
use ops::{Mul, Div, Neg};
use fmt::{Debug, LowerExp};
use mem::transmute;
use num::diy_float::Fp;
use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
use num::Float;
use num::dec2flt::num::{self, Big};

#[derive(Copy, Clone, Debug)]
pub struct Unpacked {
    pub sig: u64,
    pub k: i16,
}

impl Unpacked {
    pub fn new(sig: u64, k: i16) -> Self {
        Unpacked { sig: sig, k: k }
    }
}

/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`.
///
/// See the parent module's doc comment for why this is necessary.
///
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial.
/// The "methods" (pseudo-constants) with default implementation should not be overriden.
pub trait RawFloat : Float + Copy + Debug + LowerExp
                    + Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self>
{
    /// Get the raw binary representation of the float.
    fn transmute(self) -> u64;

    /// Transmute the raw binary representation into a float.
    fn from_bits(bits: u64) -> Self;

    /// Decode the float.
    fn unpack(self) -> Unpacked;

    /// Cast from a small integer that can be represented exactly.  Panic if the integer can't be
    /// represented, the other code in this module makes sure to never let that happen.
    fn from_int(x: u64) -> Self;

    // FIXME Everything that follows should be associated constants, but taking the value of an
    // associated constant from a type parameter does not work (yet?)
    // A possible workaround is having a `FloatInfo` struct for all the constants, but so far
    // the methods aren't painful enough to rewrite.

    /// What the name says. It's easier to hard code than juggling intrinsics and
    /// hoping LLVM constant folds it.
    fn ceil_log5_of_max_sig() -> i16;

    // A conservative bound on the decimal digits of inputs that can't produce overflow or zero or
    /// subnormals. Probably the decimal exponent of the maximum normal value, hence the name.
    fn max_normal_digits() -> usize;

    /// When the most significant decimal digit has a place value greater than this, the number
    /// is certainly rounded to infinity.
    fn inf_cutoff() -> i64;

    /// When the most significant decimal digit has a place value less than this, the number
    /// is certainly rounded to zero.
    fn zero_cutoff() -> i64;

    /// The number of bits in the exponent.
    fn exp_bits() -> u8;

    /// The number of bits in the singificand, *including* the hidden bit.
    fn sig_bits() -> u8;

    /// The number of bits in the singificand, *excluding* the hidden bit.
    fn explicit_sig_bits() -> u8 {
        Self::sig_bits() - 1
    }

    /// The maximum legal exponent in fractional representation.
    fn max_exp() -> i16 {
        (1 << (Self::exp_bits() - 1)) - 1
    }

    /// The minimum legal exponent in fractional representation, excluding subnormals.
    fn min_exp() -> i16 {
        -Self::max_exp() + 1
    }

    /// `MAX_EXP` for integral representation, i.e., with the shift applied.
    fn max_exp_int() -> i16 {
        Self::max_exp() - (Self::sig_bits() as i16 - 1)
    }

    /// `MAX_EXP` encoded (i.e., with offset bias)
    fn max_encoded_exp() -> i16 {
        (1 << Self::exp_bits()) - 1
    }

    /// `MIN_EXP` for integral representation, i.e., with the shift applied.
    fn min_exp_int() -> i16 {
        Self::min_exp() - (Self::sig_bits() as i16 - 1)
    }

    /// The maximum normalized singificand in integral representation.
    fn max_sig() -> u64 {
        (1 << Self::sig_bits()) - 1
    }

    /// The minimal normalized significand in integral representation.
    fn min_sig() -> u64 {
        1 << (Self::sig_bits() - 1)
    }
}

impl RawFloat for f32 {
    fn sig_bits() -> u8 {
        24
    }

    fn exp_bits() -> u8 {
        8
    }

    fn ceil_log5_of_max_sig() -> i16 {
        11
    }

    fn transmute(self) -> u64 {
        let bits: u32 = unsafe { transmute(self) };
        bits as u64
    }

    fn from_bits(bits: u64) -> f32 {
        assert!(bits < u32::MAX as u64, "f32::from_bits: too many bits");
        unsafe { transmute(bits as u32) }
    }

    fn unpack(self) -> Unpacked {
        let (sig, exp, _sig) = self.integer_decode();
        Unpacked::new(sig, exp)
    }

    fn from_int(x: u64) -> f32 {
        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
        debug_assert!(x as f32 == fp_to_float(Fp { f: x, e: 0 }));
        x as f32
    }

    fn max_normal_digits() -> usize {
        35
    }

    fn inf_cutoff() -> i64 {
        40
    }

    fn zero_cutoff() -> i64 {
        -48
    }
}

impl RawFloat for f64 {
    fn sig_bits() -> u8 {
        53
    }

    fn exp_bits() -> u8 {
        11
    }

    fn ceil_log5_of_max_sig() -> i16 {
        23
    }

    fn transmute(self) -> u64 {
        let bits: u64 = unsafe { transmute(self) };
        bits
    }

    fn from_bits(bits: u64) -> f64 {
        unsafe { transmute(bits) }
    }

    fn unpack(self) -> Unpacked {
        let (sig, exp, _sig) = self.integer_decode();
        Unpacked::new(sig, exp)
    }

    fn from_int(x: u64) -> f64 {
        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
        debug_assert!(x as f64 == fp_to_float(Fp { f: x, e: 0 }));
        x as f64
    }

    fn max_normal_digits() -> usize {
        305
    }

    fn inf_cutoff() -> i64 {
        310
    }

    fn zero_cutoff() -> i64 {
        -326
    }

}

/// Convert an Fp to the closest f64. Only handles number that fit into a normalized f64.
pub fn fp_to_float<T: RawFloat>(x: Fp) -> T {
    let x = x.normalize();
    // x.f is 64 bit, so x.e has a mantissa shift of 63
    let e = x.e + 63;
    if e > T::max_exp() {
        panic!("fp_to_float: exponent {} too large", e)
    }  else if e > T::min_exp() {
        encode_normal(round_normal::<T>(x))
    } else {
        panic!("fp_to_float: exponent {} too small", e)
    }
}

/// Round the 64-bit significand to 53 bit with half-to-even. Does not handle exponent overflow.
pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
    let excess = 64 - T::sig_bits() as i16;
    let half: u64 = 1 << (excess - 1);
    let (q, rem) = (x.f >> excess, x.f & ((1 << excess) - 1));
    assert_eq!(q << excess | rem, x.f);
    // Adjust mantissa shift
    let k = x.e + excess;
    if rem < half {
        Unpacked::new(q, k)
    } else if rem == half && (q % 2) == 0 {
        Unpacked::new(q, k)
    } else if q == T::max_sig() {
        Unpacked::new(T::min_sig(), k + 1)
    } else {
        Unpacked::new(q + 1, k)
    }
}

/// Inverse of `RawFloat::unpack()` for normalized numbers.
/// Panics if the significand or exponent are not valid for normalized numbers.
pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
    debug_assert!(T::min_sig() <= x.sig && x.sig <= T::max_sig(),
        "encode_normal: significand not normalized");
    // Remove the hidden bit
    let sig_enc = x.sig & !(1 << T::explicit_sig_bits());
    // Adjust the exponent for exponent bias and mantissa shift
    let k_enc = x.k + T::max_exp() + T::explicit_sig_bits() as i16;
    debug_assert!(k_enc != 0 && k_enc < T::max_encoded_exp(),
        "encode_normal: exponent out of range");
    // Leave sign bit at 0 ("+"), our numbers are all positive
    let bits = (k_enc as u64) << T::explicit_sig_bits() | sig_enc;
    T::from_bits(bits)
}

/// Construct the subnormal. A mantissa of 0 is allowed and constructs zero.
pub fn encode_subnormal<T: RawFloat>(significand: u64) -> T {
    assert!(significand < T::min_sig(), "encode_subnormal: not actually subnormal");
    // Êncoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
    T::from_bits(significand)
}

/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even.
pub fn big_to_fp(f: &Big) -> Fp {
    let end = f.bit_length();
    assert!(end != 0, "big_to_fp: unexpectedly, input is zero");
    let start = end.saturating_sub(64);
    let leading = num::get_bits(f, start, end);
    // We cut off all bits prior to the index `start`, i.e., we effectively right-shift by
    // an amount of `start`, so this is also the exponent we need.
    let e = start as i16;
    let rounded_down = Fp { f: leading, e: e }.normalize();
    // Round (half-to-even) depending on the truncated bits.
    match num::compare_with_half_ulp(f, start) {
        Less => rounded_down,
        Equal if leading % 2 == 0 => rounded_down,
        Equal | Greater => match leading.checked_add(1) {
            Some(f) => Fp { f: f, e: e }.normalize(),
            None => Fp { f: 1 << 63, e: e + 1 },
        }
    }
}

/// Find the largest floating point number strictly smaller than the argument.
/// Does not handle subnormals, zero, or exponent underflow.
pub fn prev_float<T: RawFloat>(x: T) -> T {
    match x.classify() {
        Infinite => panic!("prev_float: argument is infinite"),
        Nan => panic!("prev_float: argument is NaN"),
        Subnormal => panic!("prev_float: argument is subnormal"),
        Zero => panic!("prev_float: argument is zero"),
        Normal => {
            let Unpacked { sig, k } = x.unpack();
            if sig == T::min_sig() {
                encode_normal(Unpacked::new(T::max_sig(), k - 1))
            } else {
                encode_normal(Unpacked::new(sig - 1, k))
            }
        }
    }
}

// Find the smallest floating point number strictly larger than the argument.
// This operation is saturating, i.e. next_float(inf) == inf.
// Unlike most code in this module, this function does handle zero, subnormals, and infinities.
// However, like all other code here, it does not deal with NaN and negative numbers.
pub fn next_float<T: RawFloat>(x: T) -> T {
    match x.classify() {
        Nan => panic!("next_float: argument is NaN"),
        Infinite => T::infinity(),
        // This seems too good to be true, but it works.
        // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
        // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
        // The smallest normal number is 0x0010...0, so this corner case works as well.
        // If the increment overflows the mantissa, the carry bit increments the exponent as we
        // want, and the mantissa bits become zero. Because of the hidden bit convention, this
        // too is exactly what we want!
        // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
        Zero | Subnormal | Normal => {
            let bits: u64 = x.transmute();
            T::from_bits(bits + 1)
        }
    }
}
<commit_msg>Remove an accent in a comment<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Bit fiddling on positive IEEE 754 floats. Negative numbers aren't and needn't be handled.
//! Normal floating point numbers have a canonical representation as (frac, exp) such that the
//! value is 2^exp * (1 + sum(frac[N-i] / 2^i)) where N is the number of bits. Subnormals are
//! slightly different and weird, but the same principle applies.
//!
//! Here, however, we represent them as (sig, k) with f positive, such that the value is f * 2^e.
//! Besides making the "hidden bit" explicit, this changes the exponent by the so-called
//! mantissa shift.
//!
//! Put another way, normally floats are written as (1) but here they are written as (2):
//!
//! 1. `1.101100...11 * 2^m`
//! 2. `1101100...11 * 2^n`
//!
//! We call (1) the **fractional representation** and (2) the **integral representation**.
//!
//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
//! That algorithm needs only next_float() which does handle subnormals and zeros.
use prelude::v1::*;
use u32;
use cmp::Ordering::{Less, Equal, Greater};
use ops::{Mul, Div, Neg};
use fmt::{Debug, LowerExp};
use mem::transmute;
use num::diy_float::Fp;
use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
use num::Float;
use num::dec2flt::num::{self, Big};

#[derive(Copy, Clone, Debug)]
pub struct Unpacked {
    pub sig: u64,
    pub k: i16,
}

impl Unpacked {
    pub fn new(sig: u64, k: i16) -> Self {
        Unpacked { sig: sig, k: k }
    }
}

/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`.
///
/// See the parent module's doc comment for why this is necessary.
///
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial.
/// The "methods" (pseudo-constants) with default implementation should not be overriden.
pub trait RawFloat : Float + Copy + Debug + LowerExp
                    + Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self>
{
    /// Get the raw binary representation of the float.
    fn transmute(self) -> u64;

    /// Transmute the raw binary representation into a float.
    fn from_bits(bits: u64) -> Self;

    /// Decode the float.
    fn unpack(self) -> Unpacked;

    /// Cast from a small integer that can be represented exactly.  Panic if the integer can't be
    /// represented, the other code in this module makes sure to never let that happen.
    fn from_int(x: u64) -> Self;

    // FIXME Everything that follows should be associated constants, but taking the value of an
    // associated constant from a type parameter does not work (yet?)
    // A possible workaround is having a `FloatInfo` struct for all the constants, but so far
    // the methods aren't painful enough to rewrite.

    /// What the name says. It's easier to hard code than juggling intrinsics and
    /// hoping LLVM constant folds it.
    fn ceil_log5_of_max_sig() -> i16;

    // A conservative bound on the decimal digits of inputs that can't produce overflow or zero or
    /// subnormals. Probably the decimal exponent of the maximum normal value, hence the name.
    fn max_normal_digits() -> usize;

    /// When the most significant decimal digit has a place value greater than this, the number
    /// is certainly rounded to infinity.
    fn inf_cutoff() -> i64;

    /// When the most significant decimal digit has a place value less than this, the number
    /// is certainly rounded to zero.
    fn zero_cutoff() -> i64;

    /// The number of bits in the exponent.
    fn exp_bits() -> u8;

    /// The number of bits in the singificand, *including* the hidden bit.
    fn sig_bits() -> u8;

    /// The number of bits in the singificand, *excluding* the hidden bit.
    fn explicit_sig_bits() -> u8 {
        Self::sig_bits() - 1
    }

    /// The maximum legal exponent in fractional representation.
    fn max_exp() -> i16 {
        (1 << (Self::exp_bits() - 1)) - 1
    }

    /// The minimum legal exponent in fractional representation, excluding subnormals.
    fn min_exp() -> i16 {
        -Self::max_exp() + 1
    }

    /// `MAX_EXP` for integral representation, i.e., with the shift applied.
    fn max_exp_int() -> i16 {
        Self::max_exp() - (Self::sig_bits() as i16 - 1)
    }

    /// `MAX_EXP` encoded (i.e., with offset bias)
    fn max_encoded_exp() -> i16 {
        (1 << Self::exp_bits()) - 1
    }

    /// `MIN_EXP` for integral representation, i.e., with the shift applied.
    fn min_exp_int() -> i16 {
        Self::min_exp() - (Self::sig_bits() as i16 - 1)
    }

    /// The maximum normalized singificand in integral representation.
    fn max_sig() -> u64 {
        (1 << Self::sig_bits()) - 1
    }

    /// The minimal normalized significand in integral representation.
    fn min_sig() -> u64 {
        1 << (Self::sig_bits() - 1)
    }
}

impl RawFloat for f32 {
    fn sig_bits() -> u8 {
        24
    }

    fn exp_bits() -> u8 {
        8
    }

    fn ceil_log5_of_max_sig() -> i16 {
        11
    }

    fn transmute(self) -> u64 {
        let bits: u32 = unsafe { transmute(self) };
        bits as u64
    }

    fn from_bits(bits: u64) -> f32 {
        assert!(bits < u32::MAX as u64, "f32::from_bits: too many bits");
        unsafe { transmute(bits as u32) }
    }

    fn unpack(self) -> Unpacked {
        let (sig, exp, _sig) = self.integer_decode();
        Unpacked::new(sig, exp)
    }

    fn from_int(x: u64) -> f32 {
        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
        debug_assert!(x as f32 == fp_to_float(Fp { f: x, e: 0 }));
        x as f32
    }

    fn max_normal_digits() -> usize {
        35
    }

    fn inf_cutoff() -> i64 {
        40
    }

    fn zero_cutoff() -> i64 {
        -48
    }
}

impl RawFloat for f64 {
    fn sig_bits() -> u8 {
        53
    }

    fn exp_bits() -> u8 {
        11
    }

    fn ceil_log5_of_max_sig() -> i16 {
        23
    }

    fn transmute(self) -> u64 {
        let bits: u64 = unsafe { transmute(self) };
        bits
    }

    fn from_bits(bits: u64) -> f64 {
        unsafe { transmute(bits) }
    }

    fn unpack(self) -> Unpacked {
        let (sig, exp, _sig) = self.integer_decode();
        Unpacked::new(sig, exp)
    }

    fn from_int(x: u64) -> f64 {
        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
        debug_assert!(x as f64 == fp_to_float(Fp { f: x, e: 0 }));
        x as f64
    }

    fn max_normal_digits() -> usize {
        305
    }

    fn inf_cutoff() -> i64 {
        310
    }

    fn zero_cutoff() -> i64 {
        -326
    }

}

/// Convert an Fp to the closest f64. Only handles number that fit into a normalized f64.
pub fn fp_to_float<T: RawFloat>(x: Fp) -> T {
    let x = x.normalize();
    // x.f is 64 bit, so x.e has a mantissa shift of 63
    let e = x.e + 63;
    if e > T::max_exp() {
        panic!("fp_to_float: exponent {} too large", e)
    }  else if e > T::min_exp() {
        encode_normal(round_normal::<T>(x))
    } else {
        panic!("fp_to_float: exponent {} too small", e)
    }
}

/// Round the 64-bit significand to 53 bit with half-to-even. Does not handle exponent overflow.
pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
    let excess = 64 - T::sig_bits() as i16;
    let half: u64 = 1 << (excess - 1);
    let (q, rem) = (x.f >> excess, x.f & ((1 << excess) - 1));
    assert_eq!(q << excess | rem, x.f);
    // Adjust mantissa shift
    let k = x.e + excess;
    if rem < half {
        Unpacked::new(q, k)
    } else if rem == half && (q % 2) == 0 {
        Unpacked::new(q, k)
    } else if q == T::max_sig() {
        Unpacked::new(T::min_sig(), k + 1)
    } else {
        Unpacked::new(q + 1, k)
    }
}

/// Inverse of `RawFloat::unpack()` for normalized numbers.
/// Panics if the significand or exponent are not valid for normalized numbers.
pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
    debug_assert!(T::min_sig() <= x.sig && x.sig <= T::max_sig(),
        "encode_normal: significand not normalized");
    // Remove the hidden bit
    let sig_enc = x.sig & !(1 << T::explicit_sig_bits());
    // Adjust the exponent for exponent bias and mantissa shift
    let k_enc = x.k + T::max_exp() + T::explicit_sig_bits() as i16;
    debug_assert!(k_enc != 0 && k_enc < T::max_encoded_exp(),
        "encode_normal: exponent out of range");
    // Leave sign bit at 0 ("+"), our numbers are all positive
    let bits = (k_enc as u64) << T::explicit_sig_bits() | sig_enc;
    T::from_bits(bits)
}

/// Construct the subnormal. A mantissa of 0 is allowed and constructs zero.
pub fn encode_subnormal<T: RawFloat>(significand: u64) -> T {
    assert!(significand < T::min_sig(), "encode_subnormal: not actually subnormal");
    // Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
    T::from_bits(significand)
}

/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even.
pub fn big_to_fp(f: &Big) -> Fp {
    let end = f.bit_length();
    assert!(end != 0, "big_to_fp: unexpectedly, input is zero");
    let start = end.saturating_sub(64);
    let leading = num::get_bits(f, start, end);
    // We cut off all bits prior to the index `start`, i.e., we effectively right-shift by
    // an amount of `start`, so this is also the exponent we need.
    let e = start as i16;
    let rounded_down = Fp { f: leading, e: e }.normalize();
    // Round (half-to-even) depending on the truncated bits.
    match num::compare_with_half_ulp(f, start) {
        Less => rounded_down,
        Equal if leading % 2 == 0 => rounded_down,
        Equal | Greater => match leading.checked_add(1) {
            Some(f) => Fp { f: f, e: e }.normalize(),
            None => Fp { f: 1 << 63, e: e + 1 },
        }
    }
}

/// Find the largest floating point number strictly smaller than the argument.
/// Does not handle subnormals, zero, or exponent underflow.
pub fn prev_float<T: RawFloat>(x: T) -> T {
    match x.classify() {
        Infinite => panic!("prev_float: argument is infinite"),
        Nan => panic!("prev_float: argument is NaN"),
        Subnormal => panic!("prev_float: argument is subnormal"),
        Zero => panic!("prev_float: argument is zero"),
        Normal => {
            let Unpacked { sig, k } = x.unpack();
            if sig == T::min_sig() {
                encode_normal(Unpacked::new(T::max_sig(), k - 1))
            } else {
                encode_normal(Unpacked::new(sig - 1, k))
            }
        }
    }
}

// Find the smallest floating point number strictly larger than the argument.
// This operation is saturating, i.e. next_float(inf) == inf.
// Unlike most code in this module, this function does handle zero, subnormals, and infinities.
// However, like all other code here, it does not deal with NaN and negative numbers.
pub fn next_float<T: RawFloat>(x: T) -> T {
    match x.classify() {
        Nan => panic!("next_float: argument is NaN"),
        Infinite => T::infinity(),
        // This seems too good to be true, but it works.
        // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
        // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
        // The smallest normal number is 0x0010...0, so this corner case works as well.
        // If the increment overflows the mantissa, the carry bit increments the exponent as we
        // want, and the mantissa bits become zero. Because of the hidden bit convention, this
        // too is exactly what we want!
        // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
        Zero | Subnormal | Normal => {
            let bits: u64 = x.transmute();
            T::from_bits(bits + 1)
        }
    }
}
<|endoftext|>