<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    store_location: PathBuf,
    id: PathBuf,
}

impl StoreId {

    pub fn storified(self, store: &Store) -> StoreId {
        if self.starts_with(store.path()) {
            debug!("Not storifying {:?}, because it is already.", self);
            self
        } else {
            debug!("Create new store id out of: {:?} and {:?}", store.path(), self.id);

            let new_id = StoreId { store_location: store.path().clone(), self.id };

            debug!("Created: '{:?}'", new_id);
            new_id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

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

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.store_location;
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        StoreId(self)
    }
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<commit_msg>Remove IntoStoreId for PathBuf<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    store_location: PathBuf,
    id: PathBuf,
}

impl StoreId {

    pub fn storified(self, store: &Store) -> StoreId {
        if self.starts_with(store.path()) {
            debug!("Not storifying {:?}, because it is already.", self);
            self
        } else {
            debug!("Create new store id out of: {:?} and {:?}", store.path(), self.id);

            let new_id = StoreId { store_location: store.path().clone(), self.id };

            debug!("Created: '{:?}'", new_id);
            new_id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

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

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.store_location;
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::from(self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<|endoftext|>


<commit_before>use core::usize;

use io::{Read, Write, Seek, SeekFrom};
use str;
use string::{String, ToString};
use vec::Vec;

use syscall::{sys_open, sys_dup, sys_close, sys_execve, sys_fpath, sys_ftruncate, sys_read, sys_write, sys_lseek, sys_fsync, sys_chdir, sys_mkdir};
use syscall::common::{O_RDWR, O_CREAT, O_TRUNC, SEEK_SET, SEEK_CUR, SEEK_END};

/// A Unix-style file
pub struct File {
    /// The id for the file
    fd: usize,
}

impl File {
    pub fn exec(path: &str, args: &[&str]) -> bool {
        let path_c = path.to_string() + "\0";

        let mut args_vec: Vec<String> = Vec::new();
        for arg in args.iter() {
            args_vec.push(arg.to_string() + "\0");
        }

        let mut args_c: Vec<*const u8> = Vec::new();
        for arg_vec in args_vec.iter() {
            args_c.push(arg_vec.as_ptr());
        }
        args_c.push(0 as *const u8);

        unsafe {
            sys_execve(path_c.as_ptr(), args_c.as_ptr()) == 0
        }
    }

    /// Open a new file using a path
    pub fn open(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_RDWR, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Create a new file using a path
    pub fn create(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_CREAT | O_RDWR | O_TRUNC, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Duplicate the file
    pub fn dup(&self) -> Option<File> {
        unsafe{
            let new_fd = sys_dup(self.fd);
            if new_fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: new_fd
                })
            }
        }
    }

    /// Get the canonical path of the file
    pub fn path(&self) -> Option<String> {
        unsafe {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = sys_fpath(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(String::from_utf8_unchecked(Vec::from(&buf[0..count])))
            }
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }

    pub fn set_len(&mut self, size: usize) -> bool {
        unsafe { sys_ftruncate(self.fd, size) == 0 }
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Seek for File {
    /// Seek a given position
    fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let (whence, offset) = match pos {
            SeekFrom::Start(offset) => (SEEK_SET, offset as isize),
            SeekFrom::Current(offset) => (SEEK_CUR, offset),
            SeekFrom::End(offset) => (SEEK_END, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == usize::MAX {
            None
        } else {
            Some(position)
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}

pub struct DirEntry {
    path: String
}

impl DirEntry {
    pub fn path(&self) -> &str {
        &self.path
    }
}

pub struct ReadDir {
    file: File
}

impl Iterator for ReadDir {
    type Item = DirEntry;
    fn next(&mut self) -> Option<DirEntry> {
        let mut path = String::new();
        let mut buf: [u8; 1] = [0; 1];
        loop {
            match self.file.read(&mut buf) {
                Some(0) => break,
                Some(count) => {
                    if buf[0] == 10 {
                        break;
                    } else {
                        path.push_str(unsafe { str::from_utf8_unchecked(&buf[.. count]) });
                    }
                },
                None => break
            }
        }
        if path.is_empty() {
            None
        }else {
            Some(DirEntry {
                path: path
            })
        }
    }
}

pub fn read_dir(path: &str) -> Option<ReadDir> {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        Some(ReadDir{
            file: file
        })
    } else {
        None
    }
}

pub fn change_cwd(path: &str) -> bool {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        if let Some(file_path) = file.path() {
            if unsafe { sys_chdir((file_path + "\0").as_ptr()) } == 0 {
                return true;
            }
        }
    }

    false
}
<commit_msg>Method added to create a directory, with a given path<commit_after>use core::usize;

use io::{Read, Write, Seek, SeekFrom};
use str;
use string::{String, ToString};
use vec::Vec;

use syscall::{sys_open, sys_dup, sys_close, sys_execve, sys_fpath, sys_ftruncate, sys_read, sys_write, sys_lseek, sys_fsync, sys_chdir, sys_mkdir};
use syscall::common::{O_RDWR, O_CREAT, O_TRUNC, SEEK_SET, SEEK_CUR, SEEK_END};

/// A Unix-style file
pub struct File {
    /// The id for the file
    fd: usize,
}

impl File {
    pub fn exec(path: &str, args: &[&str]) -> bool {
        let path_c = path.to_string() + "\0";

        let mut args_vec: Vec<String> = Vec::new();
        for arg in args.iter() {
            args_vec.push(arg.to_string() + "\0");
        }

        let mut args_c: Vec<*const u8> = Vec::new();
        for arg_vec in args_vec.iter() {
            args_c.push(arg_vec.as_ptr());
        }
        args_c.push(0 as *const u8);

        unsafe {
            sys_execve(path_c.as_ptr(), args_c.as_ptr()) == 0
        }
    }

    /// Open a new file using a path
    pub fn open(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_RDWR, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Create a new file using a path
    pub fn create(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_CREAT | O_RDWR | O_TRUNC, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Duplicate the file
    pub fn dup(&self) -> Option<File> {
        unsafe{
            let new_fd = sys_dup(self.fd);
            if new_fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: new_fd
                })
            }
        }
    }

    /// Get the canonical path of the file
    pub fn path(&self) -> Option<String> {
        unsafe {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = sys_fpath(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(String::from_utf8_unchecked(Vec::from(&buf[0..count])))
            }
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }

    pub fn set_len(&mut self, size: usize) -> bool {
        unsafe { sys_ftruncate(self.fd, size) == 0 }
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Seek for File {
    /// Seek a given position
    fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let (whence, offset) = match pos {
            SeekFrom::Start(offset) => (SEEK_SET, offset as isize),
            SeekFrom::Current(offset) => (SEEK_CUR, offset),
            SeekFrom::End(offset) => (SEEK_END, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == usize::MAX {
            None
        } else {
            Some(position)
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}

pub struct DirEntry {
    path: String
}

impl DirEntry {
    pub fn path(&self) -> &str {
        &self.path
    }

    /// Create a new directory, using a path
    /// The default mode of the directory is 744
    pub fn create(path: &str) -> Option<DirEntry> {
        unsafe {
            let dir = sys_mkdir((path.to_string() + "\0").as_ptr(), 744);
            if dir == usize::MAX {
                None
            } else {
                Some(DirEntry {
                    path: path.to_string()
                })
            }
        }
    }

}

pub struct ReadDir {
    file: File
}

impl Iterator for ReadDir {
    type Item = DirEntry;
    fn next(&mut self) -> Option<DirEntry> {
        let mut path = String::new();
        let mut buf: [u8; 1] = [0; 1];
        loop {
            match self.file.read(&mut buf) {
                Some(0) => break,
                Some(count) => {
                    if buf[0] == 10 {
                        break;
                    } else {
                        path.push_str(unsafe { str::from_utf8_unchecked(&buf[.. count]) });
                    }
                },
                None => break
            }
        }
        if path.is_empty() {
            None
        }else {
            Some(DirEntry {
                path: path
            })
        }
    }
}

pub fn read_dir(path: &str) -> Option<ReadDir> {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        Some(ReadDir{
            file: file
        })
    } else {
        None
    }
}

pub fn change_cwd(path: &str) -> bool {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        if let Some(file_path) = file.path() {
            if unsafe { sys_chdir((file_path + "\0").as_ptr()) } == 0 {
                return true;
            }
        }
    }

    false
}
<|endoftext|>


<commit_before>//! Temporal quantification.

#![no_std]
#![feature(const_fn)]

use core::fmt;
use core::ops::{Add, AddAssign, Sub, SubAssign};

pub use core::time::Duration;

use serde::{Serialize, Deserialize};

/// Internal time format
/// This is public, but shouldn't be exposed to user applications,
/// only the operating system and maybe some of it's drivers
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct TimeSpec {
    pub sec: u64,
    pub nsec: u32,
}
impl TimeSpec {
    #[inline]
    pub const fn new(sec: u64, nsec: u32) -> Self {
        Self { sec, nsec }
    }

    #[inline]
    fn as_duration(&self) -> Duration {
        Duration::new(self.sec, self.nsec)
    }

    pub fn sub_instant(&self, earlier: &Self) -> Duration {
        self.checked_sub_duration(&earlier.as_duration())
            .expect("specified instant was later than self")
            .as_duration()
    }

    pub fn checked_add_duration(&self, duration: &Duration) -> Option<Self> {
        // This can overflow, so checking
        let sec: u64 = self.sec.checked_add(duration.as_secs())?;

        // This cannot overflow, as (2 * max nanoseconds) is always under u32::MAX.
        let nsec: u32 = self.nsec + duration.subsec_nanos();

        if nsec >= 1_000_000_000 {
            Some(Self {
                sec: sec.checked_add(1)?,
                nsec: nsec - 1_000_000_000,
            })
        } else {
            Some(Self { sec, nsec })
        }
    }

    pub fn checked_sub_duration(&self, duration: &Duration) -> Option<Self> {
        let mut sec: u64 = self.sec.checked_sub(duration.as_secs())?;
        let d_nsec = duration.subsec_nanos();

        if self.nsec < d_nsec {
            sec = sec.checked_sub(1)?;
            Some(Self {
                sec,
                nsec: (1_000_000_000 + self.nsec) - d_nsec,
            })
        } else {
            Some(Self {
                sec,
                nsec: self.nsec - d_nsec,
            })
        }
    }
}

/// A measurement of a monotonically nondecreasing clock.
/// Opaque and useful only with `Duration`.
///
/// Instants are always guaranteed to be no less than any previously measured
/// instant when created, and are often useful for tasks such as measuring
/// benchmarks or timing how long an operation takes.
///
/// Note, however, that instants are not guaranteed to be **steady**.  In other
/// words, each tick of the underlying clock may not be the same length (e.g.
/// some seconds may be longer than others). An instant may jump forwards or
/// experience time dilation (slow down or speed up), but it will never go
/// backwards.
///
/// Instants are opaque types that can only be compared to one another. There is
/// no method to get "the number of seconds" from an instant. Instead, it only
/// allows measuring the duration between two instants (or comparing two
/// instants).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Instant(TimeSpec);

/// An error returned from the `duration_since` and `elapsed` methods on
/// `SystemTime`, used to learn how far in the opposite direction a system time
/// lies.
///
/// # Examples
///
/// ```no_run
/// use std::thread::sleep;
/// use std::time::{Duration, SystemTime};
///
/// let sys_time = SystemTime::now();
/// sleep(Duration::from_secs(1));
/// let new_sys_time = SystemTime::now();
/// match sys_time.duration_since(new_sys_time) {
///     Ok(_) => {}
///     Err(e) => println!("SystemTimeError difference: {:?}", e.duration()),
/// }
/// ```
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SystemTimeError(Duration);

impl Instant {
    /// Used by the system clock as constructor
    ///
    /// # Safety
    ///
    /// Unsafe to prevent accidental use, as well as to remind about
    /// the monotonicity guarantees
    #[inline]
    pub unsafe fn create(ts: TimeSpec) -> Self {
        Self(ts)
    }

    /// Returns the amount of time elapsed from another instant to this one.
    ///
    /// # Panics
    ///
    /// This function will panic if `earlier` is later than `self`.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::time::{Duration, Instant};
    /// use std::thread::sleep;
    ///
    /// let now = Instant::now();
    /// sleep(Duration::new(1, 0));
    /// let new_now = Instant::now();
    /// println!("{:?}", new_now.duration_since(now));
    /// ```
    pub fn duration_since(&self, earlier: Instant) -> Duration {
        self.0.sub_instant(&earlier.0)
    }

    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
    /// otherwise.
    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
        self.0.checked_add_duration(&duration).map(Instant)
    }

    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
    /// otherwise.
    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
        self.0.checked_sub_duration(&duration).map(Instant)
    }
}

impl Add<Duration> for Instant {
    type Output = Instant;

    /// # Panics
    ///
    /// This function may panic if the resulting point in time cannot be represented by the
    /// underlying data structure. See [`checked_add`] for a version without panic.
    ///
    /// [`checked_add`]: ../../std/time/struct.Instant.html#method.checked_add
    fn add(self, other: Duration) -> Instant {
        self.checked_add(other)
            .expect("overflow when adding duration to instant")
    }
}

impl AddAssign<Duration> for Instant {
    fn add_assign(&mut self, other: Duration) {
        *self = *self + other;
    }
}

impl Sub<Duration> for Instant {
    type Output = Instant;

    fn sub(self, other: Duration) -> Instant {
        self.checked_sub(other)
            .expect("overflow when subtracting duration from instant")
    }
}

impl SubAssign<Duration> for Instant {
    fn sub_assign(&mut self, other: Duration) {
        *self = *self - other;
    }
}

impl Sub<Instant> for Instant {
    type Output = Duration;

    fn sub(self, other: Instant) -> Duration {
        self.duration_since(other)
    }
}

impl fmt::Debug for Instant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
<commit_msg>Remove unsafe from Instant::create<commit_after>//! Temporal quantification.

#![no_std]
#![feature(const_fn)]

use core::fmt;
use core::ops::{Add, AddAssign, Sub, SubAssign};

pub use core::time::Duration;

use serde::{Serialize, Deserialize};

/// Internal time format
/// This is public, but shouldn't be exposed to user applications,
/// only the operating system and maybe some of it's drivers
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct TimeSpec {
    pub sec: u64,
    pub nsec: u32,
}
impl TimeSpec {
    #[inline]
    pub const fn new(sec: u64, nsec: u32) -> Self {
        Self { sec, nsec }
    }

    #[inline]
    fn as_duration(&self) -> Duration {
        Duration::new(self.sec, self.nsec)
    }

    pub fn sub_instant(&self, earlier: &Self) -> Duration {
        self.checked_sub_duration(&earlier.as_duration())
            .expect("specified instant was later than self")
            .as_duration()
    }

    pub fn checked_add_duration(&self, duration: &Duration) -> Option<Self> {
        // This can overflow, so checking
        let sec: u64 = self.sec.checked_add(duration.as_secs())?;

        // This cannot overflow, as (2 * max nanoseconds) is always under u32::MAX.
        let nsec: u32 = self.nsec + duration.subsec_nanos();

        if nsec >= 1_000_000_000 {
            Some(Self {
                sec: sec.checked_add(1)?,
                nsec: nsec - 1_000_000_000,
            })
        } else {
            Some(Self { sec, nsec })
        }
    }

    pub fn checked_sub_duration(&self, duration: &Duration) -> Option<Self> {
        let mut sec: u64 = self.sec.checked_sub(duration.as_secs())?;
        let d_nsec = duration.subsec_nanos();

        if self.nsec < d_nsec {
            sec = sec.checked_sub(1)?;
            Some(Self {
                sec,
                nsec: (1_000_000_000 + self.nsec) - d_nsec,
            })
        } else {
            Some(Self {
                sec,
                nsec: self.nsec - d_nsec,
            })
        }
    }
}

/// A measurement of a monotonically nondecreasing clock.
/// Opaque and useful only with `Duration`.
///
/// Instants are always guaranteed to be no less than any previously measured
/// instant when created, and are often useful for tasks such as measuring
/// benchmarks or timing how long an operation takes.
///
/// Note, however, that instants are not guaranteed to be **steady**.  In other
/// words, each tick of the underlying clock may not be the same length (e.g.
/// some seconds may be longer than others). An instant may jump forwards or
/// experience time dilation (slow down or speed up), but it will never go
/// backwards.
///
/// Instants are opaque types that can only be compared to one another. There is
/// no method to get "the number of seconds" from an instant. Instead, it only
/// allows measuring the duration between two instants (or comparing two
/// instants).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Instant(TimeSpec);

/// An error returned from the `duration_since` and `elapsed` methods on
/// `SystemTime`, used to learn how far in the opposite direction a system time
/// lies.
///
/// # Examples
///
/// ```no_run
/// use std::thread::sleep;
/// use std::time::{Duration, SystemTime};
///
/// let sys_time = SystemTime::now();
/// sleep(Duration::from_secs(1));
/// let new_sys_time = SystemTime::now();
/// match sys_time.duration_since(new_sys_time) {
///     Ok(_) => {}
///     Err(e) => println!("SystemTimeError difference: {:?}", e.duration()),
/// }
/// ```
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SystemTimeError(Duration);

impl Instant {
    /// Used by the system clock as constructor
    #[inline]
    pub fn create(ts: TimeSpec) -> Self {
        Self(ts)
    }

    /// Returns the amount of time elapsed from another instant to this one.
    ///
    /// # Panics
    ///
    /// This function will panic if `earlier` is later than `self`.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use std::time::{Duration, Instant};
    /// use std::thread::sleep;
    ///
    /// let now = Instant::now();
    /// sleep(Duration::new(1, 0));
    /// let new_now = Instant::now();
    /// println!("{:?}", new_now.duration_since(now));
    /// ```
    pub fn duration_since(&self, earlier: Instant) -> Duration {
        self.0.sub_instant(&earlier.0)
    }

    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
    /// otherwise.
    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
        self.0.checked_add_duration(&duration).map(Instant)
    }

    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
    /// otherwise.
    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
        self.0.checked_sub_duration(&duration).map(Instant)
    }
}

impl Add<Duration> for Instant {
    type Output = Instant;

    /// # Panics
    ///
    /// This function may panic if the resulting point in time cannot be represented by the
    /// underlying data structure. See [`checked_add`] for a version without panic.
    ///
    /// [`checked_add`]: ../../std/time/struct.Instant.html#method.checked_add
    fn add(self, other: Duration) -> Instant {
        self.checked_add(other)
            .expect("overflow when adding duration to instant")
    }
}

impl AddAssign<Duration> for Instant {
    fn add_assign(&mut self, other: Duration) {
        *self = *self + other;
    }
}

impl Sub<Duration> for Instant {
    type Output = Instant;

    fn sub(self, other: Duration) -> Instant {
        self.checked_sub(other)
            .expect("overflow when subtracting duration from instant")
    }
}

impl SubAssign<Duration> for Instant {
    fn sub_assign(&mut self, other: Duration) {
        *self = *self - other;
    }
}

impl Sub<Instant> for Instant {
    type Output = Duration;

    fn sub(self, other: Instant) -> Duration {
        self.duration_since(other)
    }
}

impl fmt::Debug for Instant {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
<|endoftext|>


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

extern crate getopts;

use getopts::Options;
use std::process::{exit, Command, Stdio};
use std::env;

/// Take a kubos target and convert it
/// to a Rust/Clang target triplet
fn target_converter(kubos_target: &str) -> String {
    match kubos_target {
        "x86-linux-native" => String::from("x86_64-unknown-linux-gnu"),
        "kubos-linux-beaglebone-gcc" => String::from("arm-unknown-linux-gnueabihf"),
        "kubos-linux-pumpkin-mbm2-gcc" => String::from("arm-unknown-linux-gnueabihf"),
        "kubos-linux-isis-gcc" => String::from("arm-unknown-linux-gnueabi"),
        _ => {
            panic!(
                "Target '{}' not supported for cargo/yotta builds\
                 \nCurrently supported targets are:\
                 \nx86-linux-native\
                 \nkubos-linux-beaglebone-gcc\
                 \nkubos-linux-pumpkin-mbm2-gcc\
                 \nkubos-linux-isis-gcc",
                kubos_target
            )
        }
    }
}

/// Perform `cargo build` using the proper
/// Rust/Clang target triplet
fn cargo_build(target: &str, extra_params: &str) {
    let mut args = vec!["build", "--target", target];
    if !extra_params.is_empty() {
        args.push(extra_params);
    }

    let status = Command::new("cargo")
        .args(&args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()
        .unwrap();

    // Attempt to exit in a way which
    // honors the subprocess exit code
    if status.success() {
        exit(1)
    }
    exit(status.code().unwrap());
}

/// Displays usage message
fn print_usage(opts: Options) {
    let brief = "cargo-kubos is a helper utility for building \
        Kubos/yotta based modules under Cargo.\nIt is \
        used when building crates which either contain \
        a yotta module or depend on one. \
        \n\nUsage:\
        \n\tcargo kubos [options]\
        \n\tcargo kubos [options] -- [cargo options]";
    print!("{}", opts.usage(&brief));
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optopt("t", "target", "sets (Kubos) build target", "NAME");
    opts.optflag("h", "help", "Displays help");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    // Collect extra parametrs
    let extra_params = if !matches.free.is_empty() {
        let mut extras = matches.free.clone();
        // Remove `kubos` parameter
        extras.remove(0);
        extras.join(" ")
    } else {
        String::from("")
    };

    if matches.opt_present("h") {
        print_usage(opts);
    } else {
        let k_target = match matches.opt_str("t") {
            Some(t) => t,
            None => String::from("x86-linux-native"),
        };
        let c_target = target_converter(&k_target);
        env::set_var("CARGO_KUBOS_TARGET", &k_target);
        cargo_build(&c_target, &extra_params);
    }
}
<commit_msg>Refactored to allow for running any cargo command.<commit_after>//
// Copyright (C) 2017 Kubos Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

extern crate getopts;

use getopts::Options;
use std::process::{exit, Command, Stdio};
use std::env;

/// Take a kubos target and convert it
/// to a Rust/Clang target triplet
fn target_converter(kubos_target: &str) -> String {
    match kubos_target {
        "x86-linux-native" => String::from("x86_64-unknown-linux-gnu"),
        "kubos-linux-beaglebone-gcc" => String::from("arm-unknown-linux-gnueabihf"),
        "kubos-linux-pumpkin-mbm2-gcc" => String::from("arm-unknown-linux-gnueabihf"),
        "kubos-linux-isis-gcc" => String::from("arm-unknown-linux-gnueabi"),
        _ => {
            panic!(
                "Target '{}' not supported for cargo/yotta builds\
                 \nCurrently supported targets are:\
                 \nx86-linux-native\
                 \nkubos-linux-beaglebone-gcc\
                 \nkubos-linux-pumpkin-mbm2-gcc\
                 \nkubos-linux-isis-gcc",
                kubos_target
            )
        }
    }
}

/// Perform `cargo 'command'` using the proper Rust/Clang target triplet
fn cargo_command(target: String, command: String, mut extra_params: Vec<String>) {
    let mut params = vec![command, String::from("--target"), target];
    params.append(&mut extra_params);

    let status = Command::new("cargo")
        .args(&params)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()
        .unwrap();

    // Attempt to exit in a way which
    // honors the subprocess exit code
    if status.success() {
        exit(1)
    }
    exit(status.code().unwrap());
}

/// Displays usage message
fn print_usage(opts: Options) {
    let brief = "cargo-kubos is a helper utility for running \
        Cargo commands with a Kubos target attached.\nIt is \
        used when building/running/testing crates which either\
        contain a yotta module or depend on one. \
        \n\nUsage:\
        \n\tcargo kubos -c [cargo command] [options] -- [cargo options]
        \n\tcargo kubos -c build -t x86-linux-native -- -vv";
    print!("{}", opts.usage(&brief));
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.reqopt("c", "command", "cargo command to run", "COMMAND");
    opts.optopt("t", "target", "sets (Kubos) target", "NAME");
    opts.optflag("h", "help", "Displays help");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("Error - {}\n", f);
            print_usage(opts);
            return;
        }
    };

    // Collect extra parametrs
    let extra_params = if !matches.free.is_empty() {
        let mut params = matches.free.clone();
        // remove extra kubos pamatere
        params.retain(|x| x != "kubos");
        params
    } else {
        Vec::new()
    };

    if matches.opt_present("h") {
        print_usage(opts);
    } else {
        let k_target = match matches.opt_str("t") {
            Some(t) => t,
            None => String::from("x86-linux-native"),
        };
        let command = matches.opt_str("c").unwrap();
        let c_target = target_converter(&k_target);
        env::set_var("CARGO_KUBOS_TARGET", &k_target);
        cargo_command(c_target, command, extra_params);
    }
}
<|endoftext|>


<commit_before>use proc_macro2::TokenStream;
use std::fs::File;
use std::io::Write;

pub fn write(path: &str, content: TokenStream) {
    let mut file = File::create(path).unwrap();
    write!(
        file,
        "// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT\n\n"
    )
    .unwrap();
    let mut config = rustfmt::Config::default();
    config.set().emit_mode(rustfmt::EmitMode::Stdout);
    config.set().verbose(rustfmt::Verbosity::Quiet);
    config.set().format_macro_matchers(true);
    config.set().normalize_doc_attributes(true);
    let mut session = rustfmt::Session::new(config, Some(&mut file));
    session
        .format(rustfmt::Input::Text(content.to_string()))
        .unwrap();
}
<commit_msg>Use more conventional signature for file::write<commit_after>use proc_macro2::TokenStream;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn write<P: AsRef<Path>>(path: P, content: TokenStream) {
    let mut file = File::create(path).unwrap();
    write!(
        file,
        "// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT\n\n"
    )
    .unwrap();
    let mut config = rustfmt::Config::default();
    config.set().emit_mode(rustfmt::EmitMode::Stdout);
    config.set().verbose(rustfmt::Verbosity::Quiet);
    config.set().format_macro_matchers(true);
    config.set().normalize_doc_attributes(true);
    let mut session = rustfmt::Session::new(config, Some(&mut file));
    session
        .format(rustfmt::Input::Text(content.to_string()))
        .unwrap();
}
<|endoftext|>


<commit_before>#![crate_name = "nucleotide-count_test"]
#![crate_type = "lib"]

use std::collections::HashMap;

mod dna;

fn check_dna(s: &str, pairs: &[(char, uint)]) {
    // The reason for the awkward code in here is to ensure that the failure
    // message for assert_eq! is as informative as possible. A simpler
    // solution would simply check the length of the map, and then
    // check for the presence and value of each key in the given pairs vector.
    let mut m: HashMap<char, uint> = dna::nucleotide_counts(s);
    for &(k, v) in pairs.iter() {
        assert_eq!((k, m.pop(&k).unwrap()), (k, v));
    }
    // may fail with a message that clearly shows all extra pairs in the map
    assert_eq!(m.iter().collect::<Vec<(&char,&uint)>>(), vec!());
}

#[test]
#[ignore]
fn test_count_empty() {
    assert_eq!(dna::count('A', ""), 0);
}

#[test]
#[ignore]
fn test_count_repetitive_cytidine() {
    assert_eq!(dna::count('C', "CCCCC"), 5);
}

#[test]
#[ignore]
fn test_count_only_thymidine() {
    assert_eq!(dna::count('T', "GGGGGTAACCCGG"), 1);
}

#[test]
#[ignore]
fn test_count_dna_has_no_no_uracil() {
    assert_eq!(dna::count('U', "GATTACA"), 0);
}

/*
testCase "validates nucleotides" $
assertError "invalid nucleotide 'X'" $ count 'X' "GACT"
*/

#[test]
#[ignore]
fn test_nucleotide_count_empty() {
    check_dna(
        "",
        [('A', 0), ('T', 0), ('C', 0), ('G', 0)]);
}

#[test]
#[ignore]
fn test_nucleotide_count_only_guanosine() {
    check_dna(
        "GGGGGGGG",
        [('A', 0), ('T', 0), ('C', 0), ('G', 8)]);
}

#[test]
#[ignore]
fn test_nucleotide_count_counts_all() {
    check_dna(
        "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAA\
         GAGTGTCTGATAGCAGC",
        [('A', 20), ('T', 21), ('C', 12), ('G', 17)]);
}
<commit_msg>TODO: Replace me<commit_after>#![crate_name = "nucleotide-count_test"]

use std::collections::HashMap;

mod dna;

fn check_dna(s: &str, pairs: &[(char, uint)]) {
    // The reason for the awkward code in here is to ensure that the failure
    // message for assert_eq! is as informative as possible. A simpler
    // solution would simply check the length of the map, and then
    // check for the presence and value of each key in the given pairs vector.
    let mut m: HashMap<char, uint> = dna::nucleotide_counts(s);
    for &(k, v) in pairs.iter() {
        assert_eq!((k, m.pop(&k).unwrap()), (k, v));
    }
    // may fail with a message that clearly shows all extra pairs in the map
    assert_eq!(m.iter().collect::<Vec<(&char,&uint)>>(), vec!());
}

#[test]
#[ignore]
fn test_count_empty() {
    assert_eq!(dna::count('A', ""), 0);
}

#[test]
#[ignore]
fn test_count_repetitive_cytidine() {
    assert_eq!(dna::count('C', "CCCCC"), 5);
}

#[test]
#[ignore]
fn test_count_only_thymidine() {
    assert_eq!(dna::count('T', "GGGGGTAACCCGG"), 1);
}

#[test]
#[ignore]
fn test_nucleotide_count_empty() {
    check_dna(
        "",
        [('A', 0), ('T', 0), ('C', 0), ('G', 0)]);
}

#[test]
#[ignore]
fn test_nucleotide_count_only_guanosine() {
    check_dna(
        "GGGGGGGG",
        [('A', 0), ('T', 0), ('C', 0), ('G', 8)]);
}

#[test]
#[ignore]
fn test_nucleotide_count_counts_all() {
    check_dna(
        "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAA\
         GAGTGTCTGATAGCAGC",
        [('A', 20), ('T', 21), ('C', 12), ('G', 17)]);
}
<|endoftext|>


<commit_before>use insta::assert_display_snapshot_matches;

#[cfg(test)]
fn read_from_file(test_filename: &str) -> Vec<String> {
    let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
    let test_case_path: std::path::PathBuf = [&manifest_dir, "tests", "assets", test_filename]
        .iter()
        .collect();
    let test_case_file = std::fs::File::open(test_case_path).unwrap();
    let test_case_buf = std::io::BufReader::new(test_case_file);
    let lines = indentexlib::preprocessing::read_and_trim_lines(test_case_buf);
    assert!(lines.is_ok());
    lines.unwrap()
}

#[cfg(test)]
fn transpile_from_file(test_filename: &str) -> String {
    let lines = read_from_file(test_filename);

    let default_options = indentexlib::TranspileOptions {
        prepend_do_not_edit_notice: true,
    };

    indentexlib::transpile(lines, &default_options)
}

#[test]
fn vanilla_latex_is_not_modified() {
    use indentexlib::preprocessing::read_and_trim_lines;
    use std::io::BufReader;

    let lines = read_from_file("large_latex_corpus.inden.tex");
    let expected_lines = lines.clone();
    let no_prepend = indentexlib::TranspileOptions {
        prepend_do_not_edit_notice: false,
    };
    let transpiled = indentexlib::transpile(lines, &no_prepend);
    let actual_lines = read_and_trim_lines(BufReader::new(transpiled.as_bytes())).unwrap();
    assert_eq!(actual_lines, expected_lines);
}

#[test]
fn transpile_corner_cases() {
    assert_display_snapshot_matches!(
        "corner_cases",
        transpile_from_file("corner_cases.inden.tex")
    );
}

#[test]
fn transpile_envs() {
    assert_display_snapshot_matches!("envs", transpile_from_file("envs.inden.tex"));
}

#[test]
fn transpile_large_corpus() {
    assert_display_snapshot_matches!(
        "large_corpus",
        transpile_from_file("large_corpus.inden.tex")
    );
}

#[test]
fn transpile_list_like() {
    assert_display_snapshot_matches!("list_like", transpile_from_file("list_like.inden.tex"));
}

#[test]
fn transpile_mixed_tabs() {
    assert_display_snapshot_matches!("mixed_tabs", transpile_from_file("mixed_tabs.inden.tex"));
}

#[test]
fn transpile_single_line_cmds() {
    assert_display_snapshot_matches!(
        "single_line_cmds",
        transpile_from_file("single_line_cmds.inden.tex")
    );
}
<commit_msg>Migrate away from deprecated macros<commit_after>use insta::assert_display_snapshot;

#[cfg(test)]
fn read_from_file(test_filename: &str) -> Vec<String> {
    let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
    let test_case_path: std::path::PathBuf = [&manifest_dir, "tests", "assets", test_filename]
        .iter()
        .collect();
    let test_case_file = std::fs::File::open(test_case_path).unwrap();
    let test_case_buf = std::io::BufReader::new(test_case_file);
    let lines = indentexlib::preprocessing::read_and_trim_lines(test_case_buf);
    assert!(lines.is_ok());
    lines.unwrap()
}

#[cfg(test)]
fn transpile_from_file(test_filename: &str) -> String {
    let lines = read_from_file(test_filename);

    let default_options = indentexlib::TranspileOptions {
        prepend_do_not_edit_notice: true,
    };

    indentexlib::transpile(lines, &default_options)
}

#[test]
fn vanilla_latex_is_not_modified() {
    use indentexlib::preprocessing::read_and_trim_lines;
    use std::io::BufReader;

    let lines = read_from_file("large_latex_corpus.inden.tex");
    let expected_lines = lines.clone();
    let no_prepend = indentexlib::TranspileOptions {
        prepend_do_not_edit_notice: false,
    };
    let transpiled = indentexlib::transpile(lines, &no_prepend);
    let actual_lines = read_and_trim_lines(BufReader::new(transpiled.as_bytes())).unwrap();
    assert_eq!(actual_lines, expected_lines);
}

#[test]
fn transpile_corner_cases() {
    assert_display_snapshot!(
        "corner_cases",
        transpile_from_file("corner_cases.inden.tex")
    );
}

#[test]
fn transpile_envs() {
    assert_display_snapshot!("envs", transpile_from_file("envs.inden.tex"));
}

#[test]
fn transpile_large_corpus() {
    assert_display_snapshot!(
        "large_corpus",
        transpile_from_file("large_corpus.inden.tex")
    );
}

#[test]
fn transpile_list_like() {
    assert_display_snapshot!("list_like", transpile_from_file("list_like.inden.tex"));
}

#[test]
fn transpile_mixed_tabs() {
    assert_display_snapshot!("mixed_tabs", transpile_from_file("mixed_tabs.inden.tex"));
}

#[test]
fn transpile_single_line_cmds() {
    assert_display_snapshot!(
        "single_line_cmds",
        transpile_from_file("single_line_cmds.inden.tex")
    );
}
<|endoftext|>


<commit_before>use crate::error::Result;
use proc_macro2::TokenStream;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;

pub fn write<P: AsRef<Path>>(path: P, content: TokenStream) -> Result<()> {
    let mut file = File::create(path).map(BufWriter::new)?;
    write!(
        file,
        "// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT\n\n"
    )?;
    let mut config = rustfmt::Config::default();
    config.set().emit_mode(rustfmt::EmitMode::Stdout);
    config.set().verbose(rustfmt::Verbosity::Quiet);
    config.set().format_macro_matchers(true);
    config.set().normalize_doc_attributes(true);
    let mut session = rustfmt::Session::new(config, Some(&mut file));
    session.format(rustfmt::Input::Text(content.to_string()))?;
    Ok(())
}
<commit_msg>Only write codegen file if there are changes<commit_after>use crate::error::Result;
use proc_macro2::TokenStream;
use std::fs;
use std::io::Write;
use std::path::Path;

pub fn write<P: AsRef<Path>>(path: P, content: TokenStream) -> Result<()> {
    let mut formatted = Vec::new();
    write!(
        formatted,
        "// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT\n\n"
    )?;

    let mut config = rustfmt::Config::default();
    config.set().emit_mode(rustfmt::EmitMode::Stdout);
    config.set().verbose(rustfmt::Verbosity::Quiet);
    config.set().format_macro_matchers(true);
    config.set().normalize_doc_attributes(true);

    let mut session = rustfmt::Session::new(config, Some(&mut formatted));
    session.format(rustfmt::Input::Text(content.to_string()))?;
    drop(session);

    if path.as_ref().is_file() && fs::read(&path)? == formatted {
        return Ok(());
    }

    fs::write(path, formatted)?;
    Ok(())
}
<|endoftext|>


<commit_before>use core::rand::*;
use core::f64::sqrt;
use core::f64::pow;

#[deriving(Eq)]
pub struct Point {
    x : f64,
    y : f64
}

pub impl Point {
    fn new() -> Point {
        Point{x:0.0, y:0.0}
    }

    fn dist(&self, other : &Point) -> f64 {
        sqrt(pow(self.x-other.x,2.0)+pow(self.y-other.y,2.0))
    }
}

impl ToStr for Point {
    fn to_str(&self) -> ~str {
        fmt!("(%f, %f)", self.x as float, self.y as float)
    }
}

//
// * Génération aléatoire
//
impl Rand for Point {
    fn rand<R: Rng>(rng: &R) -> Point {
        Point { x: rng.gen::<f64>(), y: rng.gen::<f64>()}
    }
}

//
// * Opérateurs arithmétiques
//
// Addition
trait RhsOfAdd<Result> {
  fn add_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfAdd<Point> for Point {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x+lhs.x), y:(self.y+lhs.y)}
   }
}
impl RhsOfAdd<Point> for f64 {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (*self+lhs.x), y:(*self+lhs.y)}
   }
}
impl<Result, Rhs: RhsOfAdd<Result> > ops::Add<Rhs, Result> for Point {
  fn add(&self, rhs: &Rhs) -> Result {
    rhs.add_lhs_to(self)
  }
}
// Soustraction
trait RhsOfSub<Result> {
  fn sub_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfSub<Point> for Point {
  fn sub_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (-self.x+lhs.x), y:(-self.y+lhs.y)}
   }
}
impl RhsOfSub<Point> for f64 {
    fn sub_lhs_to(&self, lhs:&Point) -> Point {
        Point{x: lhs.x - *self, y: lhs.y-*self}
    }
}
impl<Result, Rhs: RhsOfSub<Result> > ops::Sub<Rhs, Result> for Point {
  fn sub(&self, rhs: &Rhs) -> Result {
    rhs.sub_lhs_to(self)
  }
}
// Multiplication
trait RhsOfMul<Result> {
  fn mul_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfMul<Point> for Point {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x*lhs.x), y:(self.y*lhs.y)}
   }
}
impl RhsOfMul<Point> for f64 {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self*lhs.x), y:(self*lhs.y)}
   }
}

impl<Result, Rhs: RhsOfMul<Result> > ops::Mul<Rhs, Result> for Point {
  fn mul(&self, rhs: &Rhs) -> Result {
    rhs.mul_lhs_to(self)
  }
}
// Division
trait RhsOfDiv<Result> {
  fn div_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfDiv<Point> for Point {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/self.x), y:(lhs.y/self.y)}
   }
}
impl RhsOfDiv<Point> for f64 {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/ *self), y:(lhs.y/ *self)}
   }
}
impl<Result, Rhs: RhsOfDiv<Result> > ops::Div<Rhs, Result> for Point {
  fn div(&self, rhs: &Rhs) -> Result {
    rhs.div_lhs_to(self)
  }
}

//
// * Test
//
#[test]
fn test_dist() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: 2.0, y: 3.0};
    let distance=pt1.dist(pt2);

    assert!(distance==f64::sqrt(2.0));
}

#[test]
fn test_add() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1+*pt2;

    assert!((pt3.x==0.0)&&(pt3.y==5.0));
}

#[test]
fn test_add_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1+1.0f64;

    assert!((pt3.x==2.0)&&(pt3.y==3.0));
}

#[test]
fn test_sub() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1-*pt2;
    assert!((pt3.x==2.0)&&(pt3.y==-1.0));
}
fn test_sub_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1-0.5 as f64;
    assert!((pt3.x==0.5)&&(pt3.y==1.5));
}

#[test]
fn test_mult() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)*(*pt2);
    assert!((pt3.x==-1.0)&&(pt3.y==6.0));
    let pt4=(*pt1)*(2.0 as f64);
    assert!((pt4.x==2.0)&&(pt4.y==4.0));
}

#[test]
fn test_div() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)/(*pt2);
    assert!(pt3.dist(&Point{x:-1.0, y:2.0/3.0})==0.0);
    let pt4=(*pt1)/(2.0 as f64);
    assert!((pt4.x==0.5)&&(pt4.y==1.0));
}

#[test]
fn test_rand() {
    let pt1 : Point = rand::random();
    let pt2 : Point = rand::random();
    let pt3 : Point = rand::random();

    assert!(pt1 != pt2); assert!(pt1 != pt3); assert!(pt2 != pt3);
    assert!((pt1.x>=0.0)&&(pt1.y<=1.0));
}
<commit_msg>Un nouveau constructeur pour renvoyer une direction<commit_after>use core::rand::*;
use core::f64::sqrt;
use core::f64::pow;

#[deriving(Eq)]
pub struct Point {
    x : f64,
    y : f64
}

pub impl Point {
    fn new() -> Point {
        Point{x:0.0, y:0.0}
    }

    fn new_dir() -> Point {
        let mut pt : Point =rand::random();
        pt-=0.5f64;
        pt/pt.norm2()
    }

    fn norm2(&self) -> f64 {
        sqrt(pow(self.x,2.0)+pow(self.y,2.0))
    }

    fn dist(&self, other : &Point) -> f64 {
        (*self-*other).norm2()
    }

}

impl ToStr for Point {
    fn to_str(&self) -> ~str {
        fmt!("(%f, %f)", self.x as float, self.y as float)
    }
}

//
// * Génération aléatoire
//
impl Rand for Point {
    fn rand<R: Rng>(rng: &R) -> Point {
        Point { x: rng.gen::<f64>(), y: rng.gen::<f64>()}
    }
}

//
// * Opérateurs arithmétiques
//
// Addition
trait RhsOfAdd<Result> {
  fn add_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfAdd<Point> for Point {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x+lhs.x), y:(self.y+lhs.y)}
   }
}
impl RhsOfAdd<Point> for f64 {
  fn add_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (*self+lhs.x), y:(*self+lhs.y)}
   }
}
impl<Result, Rhs: RhsOfAdd<Result> > ops::Add<Rhs, Result> for Point {
  fn add(&self, rhs: &Rhs) -> Result {
    rhs.add_lhs_to(self)
  }
}
// Soustraction
trait RhsOfSub<Result> {
  fn sub_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfSub<Point> for Point {
  fn sub_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (-self.x+lhs.x), y:(-self.y+lhs.y)}
   }
}
impl RhsOfSub<Point> for f64 {
    fn sub_lhs_to(&self, lhs:&Point) -> Point {
        Point{x: lhs.x - *self, y: lhs.y-*self}
    }
}
impl<Result, Rhs: RhsOfSub<Result> > ops::Sub<Rhs, Result> for Point {
  fn sub(&self, rhs: &Rhs) -> Result {
    rhs.sub_lhs_to(self)
  }
}
// Multiplication
trait RhsOfMul<Result> {
  fn mul_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfMul<Point> for Point {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self.x*lhs.x), y:(self.y*lhs.y)}
   }
}
impl RhsOfMul<Point> for f64 {
  fn mul_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (self*lhs.x), y:(self*lhs.y)}
   }
}

impl<Result, Rhs: RhsOfMul<Result> > ops::Mul<Rhs, Result> for Point {
  fn mul(&self, rhs: &Rhs) -> Result {
    rhs.mul_lhs_to(self)
  }
}
// Division
trait RhsOfDiv<Result> {
  fn div_lhs_to(&self, lhs: &Point) -> Result;
}
impl RhsOfDiv<Point> for Point {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/self.x), y:(lhs.y/self.y)}
   }
}
impl RhsOfDiv<Point> for f64 {
  fn div_lhs_to(&self, lhs: &Point) -> Point {
    Point{x: (lhs.x/ *self), y:(lhs.y/ *self)}
   }
}
impl<Result, Rhs: RhsOfDiv<Result> > ops::Div<Rhs, Result> for Point {
  fn div(&self, rhs: &Rhs) -> Result {
    rhs.div_lhs_to(self)
  }
}

//
// * Test
//
#[test]
fn test_norm2() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let norm=pt1.norm2();

    assert!(norm==sqrt(5.0));
}

#[test]
fn test_dist() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: 2.0, y: 3.0};
    let distance=pt1.dist(pt2);

    assert!(distance==f64::sqrt(2.0));
}

#[test]
fn test_add() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1+*pt2;

    assert!((pt3.x==0.0)&&(pt3.y==5.0));
}

#[test]
fn test_add_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1+1.0f64;

    assert!((pt3.x==2.0)&&(pt3.y==3.0));
}

#[test]
fn test_sub() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=*pt1-*pt2;
    assert!((pt3.x==2.0)&&(pt3.y==-1.0));
}
fn test_sub_float() {
    let pt1=Point{ x: 1.0, y: 2.0};
    let pt3=pt1-0.5 as f64;
    assert!((pt3.x==0.5)&&(pt3.y==1.5));
}

#[test]
fn test_mult() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)*(*pt2);
    assert!((pt3.x==-1.0)&&(pt3.y==6.0));
    let pt4=(*pt1)*(2.0 as f64);
    assert!((pt4.x==2.0)&&(pt4.y==4.0));
}

#[test]
fn test_div() {
    let pt1=@Point{ x: 1.0, y: 2.0};
    let pt2=@Point{ x: -1.0, y: 3.0};
    let pt3=(*pt1)/(*pt2);
    assert!(pt3.dist(&Point{x:-1.0, y:2.0/3.0})==0.0);
    let pt4=(*pt1)/(2.0 as f64);
    assert!((pt4.x==0.5)&&(pt4.y==1.0));
}

#[test]
fn test_new_dir() {
    let pt = Point::new_dir();
    assert!(pt.norm2()==1.0);
}

#[test]
fn test_rand() {
    let pt1 : Point = rand::random();
    let pt2 : Point = rand::random();
    let pt3 : Point = rand::random();

    assert!(pt1 != pt2); assert!(pt1 != pt3); assert!(pt2 != pt3);
    assert!((pt1.x>=0.0)&&(pt1.y<=1.0));
}
<|endoftext|>


<commit_before>use seed::prelude::*;
use crate::Msg;
use std::convert::TryInto;

use num_traits::{pow};
use num_bigint::{BigUint,ToBigUint};

mod fermat_utils {
    pub struct Fermat<'a> {
		pub n: u64,
		pub f: u64,
		pub digits: u64,
		pub prime_factors: &'a str,
        pub download: &'a str,
	}

    pub fn fermats<'a>() -> Vec<Fermat<'a>> {
        vec![
			Fermat {n: 11, f: 0, digits:  617, prime_factors: "P27567 × 974849 × 167988556341760475137 × 3560841906445833920513 × P564", download: "F0"},
            Fermat {n: 10, f: 0, digits:  309, prime_factors: "45592577 × 6487031809 × 4659775785220018543264560743076778192897 × P252", download: "F0"},
            Fermat {n:  9, f: 0, digits:  155, prime_factors: "2424833 × 7455602825647884208337395736200454918783366342657 × P99", download: "F0"},
            Fermat {n:  8, f: 0, digits:   78, prime_factors: "1238926361552897 × P62", download: "F0"},
            Fermat {n:  7, f: 0, digits:   39, prime_factors: "59649589127497217 × 5704689200685129054721", download: "F0"},
            Fermat {n:  6, f: 0, digits:   20, prime_factors: "274177 × 67280421310721", download: "F0"},
            Fermat {n:  5, f: 0, digits:   10, prime_factors: "P116 × 6700417", download: "F0"},
            Fermat {n:  4, f: 0, digits:    5, prime_factors: "P6543", download: "F0"},
            Fermat {n:  3, f: 0, digits:    3, prime_factors: "P55", download: "F0"},
            Fermat {n:  2, f: 0, digits:    2, prime_factors: "P7", download: "F0"},
            Fermat {n:  1, f: 0, digits:    1, prime_factors: "P3", download: "F0"},
            Fermat {n:  0, f: 0, digits:    1, prime_factors: "P2", download: "F0"},
        ]
    }
}

pub fn render() -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let two:usize = 2;

    let mut fermats = fermat_utils::fermats();

    for n in 0..fermats.len() {
        let download_filename:String = format!("F{}.txt",&fermats[n].n.to_string());

		let equation:String = format!("2{}+1",&(two.pow((fermats.len()-1-n).try_into().unwrap())).to_string());
        let nth_fermat:usize = fermats.len()-1-n;//counts from 11 to 0
        let fermat_value:BigUint = pow(two.to_biguint().unwrap(), pow(two, nth_fermat)) + 1.to_biguint().unwrap();

        html.push(
            tr![
                td![fermats[n].n.to_string()],//rank
				td![El::from_html(&equation)],//fermat number as a formula

                td![fermats[n].digits.to_string()],//digits in length
                td![El::from_html(fermats[n].prime_factors)],//prime factors
                td![crate::utils::save_as_file(download_filename,fermat_value.to_string())],
            ]
        );
    }

    fermats.reverse();

    div![
        h1!["The Fermat Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Id => "tbl"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Fermat"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Prime Factors"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn fermat_test<'a>() {
        let mut fermats:Vec<fermat_utils::Fermat<'a>> = fermat_utils::fermats();
		fermats.reverse();
        assert_eq!(fermats[2].prime_factors, "P7");
        assert_eq!(fermats[11].digits, 617);
    }
}<commit_msg>Removed redundent line of code<commit_after>use seed::prelude::*;
use crate::Msg;
use std::convert::TryInto;

use num_traits::{pow};
use num_bigint::{BigUint,ToBigUint};

mod fermat_utils {
    pub struct Fermat<'a> {
		pub n: u64,
		pub f: u64,
		pub digits: u64,
		pub prime_factors: &'a str,
        pub download: &'a str,
	}

    pub fn fermats<'a>() -> Vec<Fermat<'a>> {
        vec![
			Fermat {n: 11, f: 0, digits:  617, prime_factors: "P27567 × 974849 × 167988556341760475137 × 3560841906445833920513 × P564", download: "F0"},
            Fermat {n: 10, f: 0, digits:  309, prime_factors: "45592577 × 6487031809 × 4659775785220018543264560743076778192897 × P252", download: "F0"},
            Fermat {n:  9, f: 0, digits:  155, prime_factors: "2424833 × 7455602825647884208337395736200454918783366342657 × P99", download: "F0"},
            Fermat {n:  8, f: 0, digits:   78, prime_factors: "1238926361552897 × P62", download: "F0"},
            Fermat {n:  7, f: 0, digits:   39, prime_factors: "59649589127497217 × 5704689200685129054721", download: "F0"},
            Fermat {n:  6, f: 0, digits:   20, prime_factors: "274177 × 67280421310721", download: "F0"},
            Fermat {n:  5, f: 0, digits:   10, prime_factors: "P116 × 6700417", download: "F0"},
            Fermat {n:  4, f: 0, digits:    5, prime_factors: "P6543", download: "F0"},
            Fermat {n:  3, f: 0, digits:    3, prime_factors: "P55", download: "F0"},
            Fermat {n:  2, f: 0, digits:    2, prime_factors: "P7", download: "F0"},
            Fermat {n:  1, f: 0, digits:    1, prime_factors: "P3", download: "F0"},
            Fermat {n:  0, f: 0, digits:    1, prime_factors: "P2", download: "F0"},
        ]
    }
}

pub fn render() -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let two:usize = 2;

    let mut fermats = fermat_utils::fermats();

    for n in 0..fermats.len() {
        let download_filename:String = format!("F{}.txt",&fermats[n].n.to_string());

		let equation:String = format!("2{}+1",&(two.pow((fermats.len()-1-n).try_into().unwrap())).to_string());
        let nth_fermat:usize = fermats.len()-1-n;//counts from 11 to 0
        let fermat_value:BigUint = pow(two.to_biguint().unwrap(), pow(two, nth_fermat)) + 1.to_biguint().unwrap();

        html.push(
            tr![
                td![fermats[n].n.to_string()],//rank
				td![El::from_html(&equation)],//fermat number as a formula

                td![fermats[n].digits.to_string()],//digits in length
                td![El::from_html(fermats[n].prime_factors)],//prime factors
                td![crate::utils::save_as_file(download_filename,fermat_value.to_string())],
            ]
        );
    }

    div![
        h1!["The Fermat Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Id => "tbl"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Fermat"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Prime Factors"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn fermat_test<'a>() {
        let mut fermats:Vec<fermat_utils::Fermat<'a>> = fermat_utils::fermats();
		fermats.reverse();
        assert_eq!(fermats[2].prime_factors, "P7");
        assert_eq!(fermats[11].digits, 617);
    }
}<|endoftext|>


<commit_before>#![cfg(target_os = "windows")]

use std::mem;
use std::ptr;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::os::raw::c_int;
use std::sync::{
    Arc,
    Mutex
};
use std::sync::mpsc::Receiver;
use {CreationError, Event, MouseCursor};
use CursorState;

use WindowAttributes;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes;
#[derive(Clone, Default)]
pub struct PlatformSpecificHeadlessBuilderAttributes;

pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};

use winapi;
use user32;
use kernel32;

mod callback;
mod event;
mod init;
mod monitor;

lazy_static! {
    static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) };
}

/// Cursor
pub type Cursor = *const winapi::wchar_t;

/// Contains information about states and the window for the callback.
#[derive(Clone)]
pub struct WindowState {
    pub cursor: Cursor,
    pub cursor_state: CursorState,
    pub attributes: WindowAttributes
}

/// The Win32 implementation of the main `Window` object.
pub struct Window {
    /// Main handle for the window.
    window: WindowWrapper,

    /// Receiver for the events dispatched by the window callback.
    events_receiver: Receiver<Event>,

    /// The current window state.
    window_state: Arc<Mutex<WindowState>>,
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

/// A simple wrapper that destroys the window when it is destroyed.
// FIXME: remove `pub` (https://github.com/rust-lang/rust/issues/23585)
#[doc(hidden)]
pub struct WindowWrapper(pub winapi::HWND, pub winapi::HDC);

impl Drop for WindowWrapper {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::DestroyWindow(self.0);
        }
    }
}

#[derive(Clone)]
pub struct WindowProxy {
    hwnd: winapi::HWND,
}

unsafe impl Send for WindowProxy {}
unsafe impl Sync for WindowProxy {}

impl WindowProxy {
    #[inline]
    pub fn wakeup_event_loop(&self) {
        unsafe {
            user32::PostMessageA(self.hwnd, *WAKEUP_MSG_ID, 0, 0);
        }
    }
}

impl Window {
    /// See the docs in the crate root file.
    pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
               -> Result<Window, CreationError>
    {
        init::new_window(window)
    }

    /// See the docs in the crate root file.
    ///
    /// Calls SetWindowText on the HWND.
    pub fn set_title(&self, text: &str) {
        let text = OsStr::new(text).encode_wide().chain(Some(0).into_iter())
                                   .collect::<Vec<_>>();

        unsafe {
            user32::SetWindowTextW(self.window.0, text.as_ptr() as winapi::LPCWSTR);
        }
    }

    #[inline]
    pub fn show(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_SHOW);
        }
    }

    #[inline]
    pub fn hide(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_HIDE);
        }
    }

    /// See the docs in the crate root file.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        use std::mem;

        let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() };
        placement.length = mem::size_of::<winapi::WINDOWPLACEMENT>() as winapi::UINT;

        if unsafe { user32::GetWindowPlacement(self.window.0, &mut placement) } == 0 {
            return None
        }

        let ref rect = placement.rcNormalPosition;
        Some((rect.left as i32, rect.top as i32))
    }

    /// See the docs in the crate root file.
    pub fn set_position(&self, x: i32, y: i32) {
        unsafe {
            user32::SetWindowPos(self.window.0, ptr::null_mut(), x as c_int, y as c_int,
                                 0, 0, winapi::SWP_NOZORDER | winapi::SWP_NOSIZE);
            user32::UpdateWindow(self.window.0);
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetClientRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetWindowRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    pub fn set_inner_size(&self, x: u32, y: u32) {
        unsafe {
            // Calculate the outer size based upon the specified inner size
            let mut rect = winapi::RECT { top: 0, left: 0, bottom: y as winapi::LONG, right: x as winapi::LONG };
            let dw_style = user32::GetWindowLongA(self.window.0, winapi::GWL_STYLE) as winapi::DWORD;
            let b_menu = !user32::GetMenu(self.window.0).is_null() as winapi::BOOL;
            let dw_style_ex = user32::GetWindowLongA(self.window.0, winapi::GWL_EXSTYLE) as winapi::DWORD;
            user32::AdjustWindowRectEx(&mut rect, dw_style, b_menu, dw_style_ex);
            let outer_x = (rect.right - rect.left).abs() as c_int;
            let outer_y = (rect.top - rect.bottom).abs() as c_int;

            user32::SetWindowPos(self.window.0, ptr::null_mut(), 0, 0, outer_x, outer_y,
                winapi::SWP_NOZORDER | winapi::SWP_NOREPOSITION | winapi::SWP_NOMOVE);
            user32::UpdateWindow(self.window.0);
        }
    }

    #[inline]
    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy { hwnd: self.window.0 }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
        }
    }

    #[inline]
    pub fn platform_display(&self) -> *mut ::libc::c_void {
        // What should this return on win32?
        // It could be GetDC(NULL), but that requires a ReleaseDC()
        // to avoid leaking the DC.
        ptr::null_mut()
    }

    #[inline]
    pub fn platform_window(&self) -> *mut ::libc::c_void {
        self.window.0 as *mut ::libc::c_void
    }

    #[inline]
    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    #[inline]
    pub fn set_cursor(&self, _cursor: MouseCursor) {
        let cursor_id = match _cursor {
            MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW,
            MouseCursor::Hand => winapi::IDC_HAND,
            MouseCursor::Crosshair => winapi::IDC_CROSS,
            MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM,
            MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO,
            MouseCursor::EResize => winapi::IDC_SIZEWE,
            MouseCursor::NResize => winapi::IDC_SIZENS,
            MouseCursor::WResize => winapi::IDC_SIZEWE,
            MouseCursor::SResize => winapi::IDC_SIZENS,
            MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE,
            MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS,
            MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT,
            MouseCursor::Help => winapi::IDC_HELP,
            _ => winapi::IDC_ARROW, // use arrow for the missing cases.
        };

        let mut cur = self.window_state.lock().unwrap();
        cur.cursor = cursor_id;
    }

    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        let mut current_state = self.window_state.lock().unwrap();

        let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
        let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };

        let res = match (state, current_state.cursor_state) {
            (CursorState::Normal, CursorState::Normal) => Ok(()),
            (CursorState::Hide, CursorState::Hide) => Ok(()),
            (CursorState::Grab, CursorState::Grab) => Ok(()),

            (CursorState::Hide, CursorState::Normal) => {
                current_state.cursor_state = CursorState::Hide;
                Ok(())
            },

            (CursorState::Normal, CursorState::Hide) => {
                current_state.cursor_state = CursorState::Normal;
                Ok(())
            },

            (CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
                unsafe {
                    let mut rect = mem::uninitialized();
                    if user32::GetClientRect(self.window.0, &mut rect) == 0 {
                        return Err(format!("GetWindowRect failed"));
                    }
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.left));
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.right));
                    if user32::ClipCursor(&rect) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Grab;
                    Ok(())
                }
            },

            (CursorState::Normal, CursorState::Grab) => {
                unsafe {
                    if user32::ClipCursor(ptr::null()) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Normal;
                    Ok(())
                }
            },

            _ => unimplemented!(),
        };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 0) };

        res
    }

    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        let mut point = winapi::POINT {
            x: x,
            y: y,
        };

        unsafe {
            if user32::ClientToScreen(self.window.0, &mut point) == 0 {
                return Err(());
            }

            if user32::SetCursorPos(point.x, point.y) == 0 {
                return Err(());
            }
        }

        Ok(())
    }
}

impl Drop for Window {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::PostMessageW(self.window.0, winapi::WM_DESTROY, 0, 0);
        }
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.try_recv().ok()
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.recv().ok()
    }
}
<commit_msg>Removed pub fields when not needed<commit_after>#![cfg(target_os = "windows")]

use std::mem;
use std::ptr;
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::os::raw::c_int;
use std::sync::{
    Arc,
    Mutex
};
use std::sync::mpsc::Receiver;
use {CreationError, Event, MouseCursor};
use CursorState;

use WindowAttributes;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes;
#[derive(Clone, Default)]
pub struct PlatformSpecificHeadlessBuilderAttributes;

pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};

use winapi;
use user32;
use kernel32;

mod callback;
mod event;
mod init;
mod monitor;

lazy_static! {
    static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) };
}

/// Cursor
pub type Cursor = *const winapi::wchar_t;

/// Contains information about states and the window for the callback.
#[derive(Clone)]
pub struct WindowState {
    pub cursor: Cursor,
    pub cursor_state: CursorState,
    pub attributes: WindowAttributes
}

/// The Win32 implementation of the main `Window` object.
pub struct Window {
    /// Main handle for the window.
    window: WindowWrapper,

    /// Receiver for the events dispatched by the window callback.
    events_receiver: Receiver<Event>,

    /// The current window state.
    window_state: Arc<Mutex<WindowState>>,
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

/// A simple wrapper that destroys the window when it is destroyed.
#[doc(hidden)]
pub struct WindowWrapper(winapi::HWND, winapi::HDC);

impl Drop for WindowWrapper {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::DestroyWindow(self.0);
        }
    }
}

#[derive(Clone)]
pub struct WindowProxy {
    hwnd: winapi::HWND,
}

unsafe impl Send for WindowProxy {}
unsafe impl Sync for WindowProxy {}

impl WindowProxy {
    #[inline]
    pub fn wakeup_event_loop(&self) {
        unsafe {
            user32::PostMessageA(self.hwnd, *WAKEUP_MSG_ID, 0, 0);
        }
    }
}

impl Window {
    /// See the docs in the crate root file.
    pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
               -> Result<Window, CreationError>
    {
        init::new_window(window)
    }

    /// See the docs in the crate root file.
    ///
    /// Calls SetWindowText on the HWND.
    pub fn set_title(&self, text: &str) {
        let text = OsStr::new(text).encode_wide().chain(Some(0).into_iter())
                                   .collect::<Vec<_>>();

        unsafe {
            user32::SetWindowTextW(self.window.0, text.as_ptr() as winapi::LPCWSTR);
        }
    }

    #[inline]
    pub fn show(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_SHOW);
        }
    }

    #[inline]
    pub fn hide(&self) {
        unsafe {
            user32::ShowWindow(self.window.0, winapi::SW_HIDE);
        }
    }

    /// See the docs in the crate root file.
    pub fn get_position(&self) -> Option<(i32, i32)> {
        use std::mem;

        let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() };
        placement.length = mem::size_of::<winapi::WINDOWPLACEMENT>() as winapi::UINT;

        if unsafe { user32::GetWindowPlacement(self.window.0, &mut placement) } == 0 {
            return None
        }

        let ref rect = placement.rcNormalPosition;
        Some((rect.left as i32, rect.top as i32))
    }

    /// See the docs in the crate root file.
    pub fn set_position(&self, x: i32, y: i32) {
        unsafe {
            user32::SetWindowPos(self.window.0, ptr::null_mut(), x as c_int, y as c_int,
                                 0, 0, winapi::SWP_NOZORDER | winapi::SWP_NOSIZE);
            user32::UpdateWindow(self.window.0);
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetClientRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        let mut rect: winapi::RECT = unsafe { mem::uninitialized() };

        if unsafe { user32::GetWindowRect(self.window.0, &mut rect) } == 0 {
            return None
        }

        Some((
            (rect.right - rect.left) as u32,
            (rect.bottom - rect.top) as u32
        ))
    }

    /// See the docs in the crate root file.
    pub fn set_inner_size(&self, x: u32, y: u32) {
        unsafe {
            // Calculate the outer size based upon the specified inner size
            let mut rect = winapi::RECT { top: 0, left: 0, bottom: y as winapi::LONG, right: x as winapi::LONG };
            let dw_style = user32::GetWindowLongA(self.window.0, winapi::GWL_STYLE) as winapi::DWORD;
            let b_menu = !user32::GetMenu(self.window.0).is_null() as winapi::BOOL;
            let dw_style_ex = user32::GetWindowLongA(self.window.0, winapi::GWL_EXSTYLE) as winapi::DWORD;
            user32::AdjustWindowRectEx(&mut rect, dw_style, b_menu, dw_style_ex);
            let outer_x = (rect.right - rect.left).abs() as c_int;
            let outer_y = (rect.top - rect.bottom).abs() as c_int;

            user32::SetWindowPos(self.window.0, ptr::null_mut(), 0, 0, outer_x, outer_y,
                winapi::SWP_NOZORDER | winapi::SWP_NOREPOSITION | winapi::SWP_NOMOVE);
            user32::UpdateWindow(self.window.0);
        }
    }

    #[inline]
    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy { hwnd: self.window.0 }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self,
        }
    }

    /// See the docs in the crate root file.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self,
        }
    }

    #[inline]
    pub fn platform_display(&self) -> *mut ::libc::c_void {
        // What should this return on win32?
        // It could be GetDC(NULL), but that requires a ReleaseDC()
        // to avoid leaking the DC.
        ptr::null_mut()
    }

    #[inline]
    pub fn platform_window(&self) -> *mut ::libc::c_void {
        self.window.0 as *mut ::libc::c_void
    }

    #[inline]
    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    #[inline]
    pub fn set_cursor(&self, _cursor: MouseCursor) {
        let cursor_id = match _cursor {
            MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW,
            MouseCursor::Hand => winapi::IDC_HAND,
            MouseCursor::Crosshair => winapi::IDC_CROSS,
            MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM,
            MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO,
            MouseCursor::EResize => winapi::IDC_SIZEWE,
            MouseCursor::NResize => winapi::IDC_SIZENS,
            MouseCursor::WResize => winapi::IDC_SIZEWE,
            MouseCursor::SResize => winapi::IDC_SIZENS,
            MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE,
            MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS,
            MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT,
            MouseCursor::Help => winapi::IDC_HELP,
            _ => winapi::IDC_ARROW, // use arrow for the missing cases.
        };

        let mut cur = self.window_state.lock().unwrap();
        cur.cursor = cursor_id;
    }

    pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
        let mut current_state = self.window_state.lock().unwrap();

        let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) };
        let current_thread_id = unsafe { kernel32::GetCurrentThreadId() };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) };

        let res = match (state, current_state.cursor_state) {
            (CursorState::Normal, CursorState::Normal) => Ok(()),
            (CursorState::Hide, CursorState::Hide) => Ok(()),
            (CursorState::Grab, CursorState::Grab) => Ok(()),

            (CursorState::Hide, CursorState::Normal) => {
                current_state.cursor_state = CursorState::Hide;
                Ok(())
            },

            (CursorState::Normal, CursorState::Hide) => {
                current_state.cursor_state = CursorState::Normal;
                Ok(())
            },

            (CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => {
                unsafe {
                    let mut rect = mem::uninitialized();
                    if user32::GetClientRect(self.window.0, &mut rect) == 0 {
                        return Err(format!("GetWindowRect failed"));
                    }
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.left));
                    user32::ClientToScreen(self.window.0, mem::transmute(&mut rect.right));
                    if user32::ClipCursor(&rect) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Grab;
                    Ok(())
                }
            },

            (CursorState::Normal, CursorState::Grab) => {
                unsafe {
                    if user32::ClipCursor(ptr::null()) == 0 {
                        return Err(format!("ClipCursor failed"));
                    }
                    current_state.cursor_state = CursorState::Normal;
                    Ok(())
                }
            },

            _ => unimplemented!(),
        };

        unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 0) };

        res
    }

    #[inline]
    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        let mut point = winapi::POINT {
            x: x,
            y: y,
        };

        unsafe {
            if user32::ClientToScreen(self.window.0, &mut point) == 0 {
                return Err(());
            }

            if user32::SetCursorPos(point.x, point.y) == 0 {
                return Err(());
            }
        }

        Ok(())
    }
}

impl Drop for Window {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            user32::PostMessageW(self.window.0, winapi::WM_DESTROY, 0, 0);
        }
    }
}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.try_recv().ok()
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    #[inline]
    fn next(&mut self) -> Option<Event> {
        self.window.events_receiver.recv().ok()
    }
}
<|endoftext|>