<commit_before>//! Error types for conversion to integral types.

use crate::convert::Infallible;
use crate::fmt;

/// The error type returned when a checked integral type conversion fails.
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromIntError(pub(crate) ());

impl TryFromIntError {
    #[unstable(
        feature = "int_error_internals",
        reason = "available through Error trait and this method should \
                  not be exposed publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        "out of range integral type conversion attempted"
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for TryFromIntError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(fmt)
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
    fn from(x: Infallible) -> TryFromIntError {
        match x {}
    }
}

#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
    fn from(never: !) -> TryFromIntError {
        // Match rather than coerce to make sure that code like
        // `From<Infallible> for TryFromIntError` above will keep working
        // when `Infallible` becomes an alias to `!`.
        match never {}
    }
}

/// An error which can be returned when parsing an integer.
///
/// This error is used as the error type for the `from_str_radix()` functions
/// on the primitive integer types, such as [`i8::from_str_radix`].
///
/// # Potential causes
///
/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
/// in the string e.g., when it is obtained from the standard input.
/// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
///
/// # Example
///
/// ```
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {}", e);
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseIntError {
    pub(super) kind: IntErrorKind,
}

/// Enum to store the various types of errors that can cause parsing an integer to fail.
///
/// # Example
///
/// ```
/// #![feature(int_error_matching)]
///
/// # fn main() {
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {:?}", e.kind());
/// }
/// # }
/// ```
#[unstable(
    feature = "int_error_matching",
    reason = "it can be useful to match errors when making error messages \
              for integer parsing",
    issue = "22639"
)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum IntErrorKind {
    /// Value being parsed is empty.
    ///
    /// Among other causes, this variant will be constructed when parsing an empty string.
    Empty,
    /// Contains an invalid digit in its context.
    ///
    /// Among other causes, this variant will be constructed when parsing a string that
    /// contains a non-ASCII char.
    ///
    /// This variant is also constructed when a `+` or `-` is misplaced within a string
    /// either on its own or in the middle of a number.
    InvalidDigit,
    /// Integer is too large to store in target integer type.
    PosOverflow,
    /// Integer is too small to store in target integer type.
    NegOverflow,
    /// Value was Zero
    ///
    /// This variant will be emitted when the parsing string has a value of zero, which
    /// would be illegal for non-zero types.
    Zero,
}

impl ParseIntError {
    /// Outputs the detailed cause of parsing an integer failing.
    #[unstable(
        feature = "int_error_matching",
        reason = "it can be useful to match errors when making error messages \
              for integer parsing",
        issue = "22639"
    )]
    pub fn kind(&self) -> &IntErrorKind {
        &self.kind
    }
    #[unstable(
        feature = "int_error_internals",
        reason = "available through Error trait and this method should \
                  not be exposed publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            IntErrorKind::Empty => "cannot parse integer from empty string",
            IntErrorKind::InvalidDigit => "invalid digit found in string",
            IntErrorKind::PosOverflow => "number too large to fit in target type",
            IntErrorKind::NegOverflow => "number too small to fit in target type",
            IntErrorKind::Zero => "number would be zero for non-zero type",
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseIntError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(f)
    }
}
<commit_msg>Fix link<commit_after>//! Error types for conversion to integral types.

use crate::convert::Infallible;
use crate::fmt;

/// The error type returned when a checked integral type conversion fails.
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromIntError(pub(crate) ());

impl TryFromIntError {
    #[unstable(
        feature = "int_error_internals",
        reason = "available through Error trait and this method should \
                  not be exposed publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        "out of range integral type conversion attempted"
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for TryFromIntError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(fmt)
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
    fn from(x: Infallible) -> TryFromIntError {
        match x {}
    }
}

#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
    fn from(never: !) -> TryFromIntError {
        // Match rather than coerce to make sure that code like
        // `From<Infallible> for TryFromIntError` above will keep working
        // when `Infallible` becomes an alias to `!`.
        match never {}
    }
}

/// An error which can be returned when parsing an integer.
///
/// This error is used as the error type for the `from_str_radix()` functions
/// on the primitive integer types, such as [`i8::from_str_radix`].
///
/// # Potential causes
///
/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
/// in the string e.g., when it is obtained from the standard input.
/// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
///
/// # Example
///
/// ```
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {}", e);
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseIntError {
    pub(super) kind: IntErrorKind,
}

/// Enum to store the various types of errors that can cause parsing an integer to fail.
///
/// # Example
///
/// ```
/// #![feature(int_error_matching)]
///
/// # fn main() {
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {:?}", e.kind());
/// }
/// # }
/// ```
#[unstable(
    feature = "int_error_matching",
    reason = "it can be useful to match errors when making error messages \
              for integer parsing",
    issue = "22639"
)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum IntErrorKind {
    /// Value being parsed is empty.
    ///
    /// Among other causes, this variant will be constructed when parsing an empty string.
    Empty,
    /// Contains an invalid digit in its context.
    ///
    /// Among other causes, this variant will be constructed when parsing a string that
    /// contains a non-ASCII char.
    ///
    /// This variant is also constructed when a `+` or `-` is misplaced within a string
    /// either on its own or in the middle of a number.
    InvalidDigit,
    /// Integer is too large to store in target integer type.
    PosOverflow,
    /// Integer is too small to store in target integer type.
    NegOverflow,
    /// Value was Zero
    ///
    /// This variant will be emitted when the parsing string has a value of zero, which
    /// would be illegal for non-zero types.
    Zero,
}

impl ParseIntError {
    /// Outputs the detailed cause of parsing an integer failing.
    #[unstable(
        feature = "int_error_matching",
        reason = "it can be useful to match errors when making error messages \
              for integer parsing",
        issue = "22639"
    )]
    pub fn kind(&self) -> &IntErrorKind {
        &self.kind
    }
    #[unstable(
        feature = "int_error_internals",
        reason = "available through Error trait and this method should \
                  not be exposed publicly",
        issue = "none"
    )]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            IntErrorKind::Empty => "cannot parse integer from empty string",
            IntErrorKind::InvalidDigit => "invalid digit found in string",
            IntErrorKind::PosOverflow => "number too large to fit in target type",
            IntErrorKind::NegOverflow => "number too small to fit in target type",
            IntErrorKind::Zero => "number would be zero for non-zero type",
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseIntError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.__description().fmt(f)
    }
}
<|endoftext|>


<commit_before>extern crate phf_codegen;

mod static_atom_list;

use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;

fn main() {
    let mut set = phf_codegen::OrderedSet::new();
    for &atom in static_atom_list::ATOMS {
        set.entry(atom);
    }

    let path = Path::new(env!("OUT_DIR")).join("static_atom_set.rs");
    let mut file = BufWriter::new(File::create(&path).unwrap());
    write!(&mut file, "pub static STATIC_ATOM_SET: phf::OrderedSet<&'static str> = ").unwrap();
    set.build(&mut file).unwrap();
    write!(&mut file, ";\n").unwrap();
}
<commit_msg>Fix cross-compilation error in shared/build.rs<commit_after>extern crate phf_codegen;

mod static_atom_list;

use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;

fn main() {
    let mut set = phf_codegen::OrderedSet::new();
    for &atom in static_atom_list::ATOMS {
        set.entry(atom);
    }

    let path = Path::new(&std::env::var("OUT_DIR").unwrap()).join("static_atom_set.rs");
    let mut file = BufWriter::new(File::create(&path).unwrap());
    write!(&mut file, "pub static STATIC_ATOM_SET: phf::OrderedSet<&'static str> = ").unwrap();
    set.build(&mut file).unwrap();
    write!(&mut file, ";\n").unwrap();
}
<|endoftext|>


<commit_before>#![no_std]
#[macro_use]
extern crate generic_array;
use generic_array::typenum::{U3, U97};
use generic_array::GenericArray;
use core::ops::Drop;

#[test]
fn test() {
    let mut list97 = [0; 97];
    for i in 0..97 {
        list97[i] = i as i32;
    }
    let l : GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
    assert_eq!(l[0], 0);
    assert_eq!(l[1], 1);
    assert_eq!(l[32], 32);
    assert_eq!(l[56], 56);
}

#[allow(non_upper_case_globals)]
static mut drop_counter: u32 = 0;

#[derive(Clone)]
struct TestDrop(u32);

impl Drop for TestDrop {
    fn drop(&mut self) {
        unsafe {
            drop_counter += 1;
        }
    }
}

#[test]
fn test_drop() {
    unsafe {
        drop_counter = 0;
    }
    {
        // This clones the structs, so we will have 6 drops, not 3
        let _: GenericArray<TestDrop, U3> = arr![TestDrop; TestDrop(1), TestDrop(2), TestDrop(3)];
    }
    unsafe {
        assert_eq!(drop_counter, 6);    // 6 drops, as explained above
    }
}

#[test]
fn test_arr() {
    let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
    assert_eq!(test[1], 2);
}

#[test]
fn test_copy() {
    let test = arr![u32; 1, 2, 3];
    let test2 = test;
    // if GenericArray is not copy, this should fail as a use of a moved value
    assert_eq!(test[1], 2);
    assert_eq!(test2[0], 1);
}

#[test]
fn test_iter_flat_map() {
    assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10));
}

#[test]
fn test_from_slice() {
    let arr = [1,2,3,4];
    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
    assert_eq!(&arr[..3], gen_arr.as_slice());
}

#[test]
fn test_from_mut_slice() {
    let mut arr = [1,2,3,4];
    {
        let mut gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
        gen_arr[2] = 10;
    }
    assert_eq!(arr, [1,2,10,4]);
}

#[test]
fn test_unit_macro(){
    let arr = arr![f32; 3.14];
    assert_eq!(arr[0], 3.14);
}

#[test]
fn test_empty_macro(){
    let arr = arr![f32;];
}

/// This test should cause a helpful compile error if uncommented.
// #[test]
// fn test_empty_macro2(){
//     let arr = arr![];
// }

#[cfg(feature="serde")]
mod impl_serde {
    extern crate serde_json;

    use generic_array::GenericArray;
    use generic_array::typenum::U6;

    #[test]
    fn test_serde_implementation() {
        let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
        let string = serde_json::to_string(&array).unwrap();
        assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");

        let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
        assert_eq!(test_array, array);
    }
}
<commit_msg>add a test for GenericArray::default()<commit_after>#![no_std]
#[macro_use]
extern crate generic_array;
use generic_array::typenum::{U1, U3, U97};
use generic_array::GenericArray;
use core::ops::Drop;

#[test]
fn test() {
    let mut list97 = [0; 97];
    for i in 0..97 {
        list97[i] = i as i32;
    }
    let l : GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
    assert_eq!(l[0], 0);
    assert_eq!(l[1], 1);
    assert_eq!(l[32], 32);
    assert_eq!(l[56], 56);
}

#[allow(non_upper_case_globals)]
static mut drop_counter: u32 = 0;

#[derive(Clone)]
struct TestDrop(u32);

impl Drop for TestDrop {
    fn drop(&mut self) {
        unsafe {
            drop_counter += 1;
        }
    }
}

#[test]
fn test_drop() {
    unsafe {
        drop_counter = 0;
    }
    {
        // This clones the structs, so we will have 6 drops, not 3
        let _: GenericArray<TestDrop, U3> = arr![TestDrop; TestDrop(1), TestDrop(2), TestDrop(3)];
    }
    unsafe {
        assert_eq!(drop_counter, 6);    // 6 drops, as explained above
    }
}

#[test]
fn test_arr() {
    let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
    assert_eq!(test[1], 2);
}

#[test]
fn test_copy() {
    let test = arr![u32; 1, 2, 3];
    let test2 = test;
    // if GenericArray is not copy, this should fail as a use of a moved value
    assert_eq!(test[1], 2);
    assert_eq!(test2[0], 1);
}

#[test]
fn test_iter_flat_map() {
    assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10));
}

#[test]
fn test_from_slice() {
    let arr = [1,2,3,4];
    let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
    assert_eq!(&arr[..3], gen_arr.as_slice());
}

#[test]
fn test_from_mut_slice() {
    let mut arr = [1,2,3,4];
    {
        let mut gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
        gen_arr[2] = 10;
    }
    assert_eq!(arr, [1,2,10,4]);
}

#[test]
fn test_default() {
    let arr = GenericArray::<u8, U1>::default();
    assert_eq!(arr[0], 0);
}

#[test]
fn test_unit_macro() {
    let arr = arr![f32; 3.14];
    assert_eq!(arr[0], 3.14);
}

#[test]
fn test_empty_macro(){
    let arr = arr![f32;];
}

/// This test should cause a helpful compile error if uncommented.
// #[test]
// fn test_empty_macro2(){
//     let arr = arr![];
// }

#[cfg(feature="serde")]
mod impl_serde {
    extern crate serde_json;

    use generic_array::GenericArray;
    use generic_array::typenum::U6;

    #[test]
    fn test_serde_implementation() {
        let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
        let string = serde_json::to_string(&array).unwrap();
        assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");

        let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
        assert_eq!(test_array, array);
    }
}
<|endoftext|>


<commit_before>use super::*;

pub(super) fn opt_type_param_list(p: &mut Parser) {
    if !p.at(L_ANGLE) {
        return;
    }
    type_param_list(p);
}

fn type_param_list(p: &mut Parser) {
    assert!(p.at(L_ANGLE));
    let m = p.start();
    p.bump();

    while !p.at(EOF) && !p.at(R_ANGLE) {
        match p.current() {
            LIFETIME => lifetime_param(p),
            IDENT => type_param(p),
            _ => p.err_and_bump("expected type parameter"),
        }
        if !p.at(R_ANGLE) && !p.expect(COMMA) {
            break;
        }
    }
    p.expect(R_ANGLE);
    m.complete(p, TYPE_PARAM_LIST);
}

fn lifetime_param(p: &mut Parser) {
    assert!(p.at(LIFETIME));
    let m = p.start();
    p.bump();
    if p.at(COLON) {
        lifetime_bounds(p);
    }
    m.complete(p, LIFETIME_PARAM);
}

fn type_param(p: &mut Parser) {
    assert!(p.at(IDENT));
    let m = p.start();
    name(p);
    if p.at(COLON) {
        bounds(p);
    }
    // test type_param_default
    // struct S<T = i32>;
    if p.at(EQ) {
        p.bump();
        types::type_(p)
    }
    m.complete(p, TYPE_PARAM);
}

// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
    assert!(p.at(COLON));
    p.bump();
    bounds_without_colon(p);
}

fn lifetime_bounds(p: &mut Parser) {
    assert!(p.at(COLON));
    p.bump();
    while p.at(LIFETIME) {
        p.bump();
        if !p.eat(PLUS) {
            break;
        }
    }
}

pub(super) fn bounds_without_colon(p: &mut Parser) {
    loop {
        let has_paren = p.eat(L_PAREN);
        p.eat(QUESTION);
        match p.current() {
            LIFETIME => p.bump(),
            FOR_KW => types::for_type(p),
            _ if paths::is_path_start(p) => types::path_type(p),
            _ => break,
        }
        if has_paren {
            p.expect(R_PAREN);
        }
        if !p.eat(PLUS) {
            break;
        }
    }
}

// test where_clause
// fn foo()
// where
//    'a: 'b + 'c,
//    T: Clone + Copy + 'static,
//    Iterator::Item: 'a,
// {}
pub(super) fn opt_where_clause(p: &mut Parser) {
    if !p.at(WHERE_KW) {
        return;
    }
    let m = p.start();
    p.bump();
    loop {
        if !(paths::is_path_start(p) || p.current() == LIFETIME || p.current() == FOR_KW) {
            break;
        }
        where_predicate(p);
        if p.current() != L_CURLY && p.current() != SEMI {
            p.expect(COMMA);
        }
    }
    m.complete(p, WHERE_CLAUSE);
}

fn where_predicate(p: &mut Parser) {
    let m = p.start();
    match p.current() {
        LIFETIME => {
            p.bump();
            if p.at(COLON) {
                lifetime_bounds(p);
            } else {
                p.error("expected colon");
            }
        }
        _ => {
            // test where_pred_for
            // fn test<F>()
            // where
            //    for<'a> F: Fn(&'a str)
            // { }
            if p.at(FOR_KW) {
                types::for_binder(p);
            }
            if paths::is_path_start(p) || p.at(L_ANGLE) {
                types::path_type_(p, false);
            } else {
                p.error("expected a type");
            }
            if p.at(COLON) {
                bounds(p);
            } else {
                p.error("expected colon");
            }
        }
    }
    m.complete(p, WHERE_PRED);
}
<commit_msg>Don't require a command before EQ in a where clause<commit_after>use super::*;

pub(super) fn opt_type_param_list(p: &mut Parser) {
    if !p.at(L_ANGLE) {
        return;
    }
    type_param_list(p);
}

fn type_param_list(p: &mut Parser) {
    assert!(p.at(L_ANGLE));
    let m = p.start();
    p.bump();

    while !p.at(EOF) && !p.at(R_ANGLE) {
        match p.current() {
            LIFETIME => lifetime_param(p),
            IDENT => type_param(p),
            _ => p.err_and_bump("expected type parameter"),
        }
        if !p.at(R_ANGLE) && !p.expect(COMMA) {
            break;
        }
    }
    p.expect(R_ANGLE);
    m.complete(p, TYPE_PARAM_LIST);
}

fn lifetime_param(p: &mut Parser) {
    assert!(p.at(LIFETIME));
    let m = p.start();
    p.bump();
    if p.at(COLON) {
        lifetime_bounds(p);
    }
    m.complete(p, LIFETIME_PARAM);
}

fn type_param(p: &mut Parser) {
    assert!(p.at(IDENT));
    let m = p.start();
    name(p);
    if p.at(COLON) {
        bounds(p);
    }
    // test type_param_default
    // struct S<T = i32>;
    if p.at(EQ) {
        p.bump();
        types::type_(p)
    }
    m.complete(p, TYPE_PARAM);
}

// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
    assert!(p.at(COLON));
    p.bump();
    bounds_without_colon(p);
}

fn lifetime_bounds(p: &mut Parser) {
    assert!(p.at(COLON));
    p.bump();
    while p.at(LIFETIME) {
        p.bump();
        if !p.eat(PLUS) {
            break;
        }
    }
}

pub(super) fn bounds_without_colon(p: &mut Parser) {
    loop {
        let has_paren = p.eat(L_PAREN);
        p.eat(QUESTION);
        match p.current() {
            LIFETIME => p.bump(),
            FOR_KW => types::for_type(p),
            _ if paths::is_path_start(p) => types::path_type(p),
            _ => break,
        }
        if has_paren {
            p.expect(R_PAREN);
        }
        if !p.eat(PLUS) {
            break;
        }
    }
}

// test where_clause
// fn foo()
// where
//    'a: 'b + 'c,
//    T: Clone + Copy + 'static,
//    Iterator::Item: 'a,
// {}
pub(super) fn opt_where_clause(p: &mut Parser) {
    if !p.at(WHERE_KW) {
        return;
    }
    let m = p.start();
    p.bump();
    loop {
        if !(paths::is_path_start(p) || p.current() == LIFETIME || p.current() == FOR_KW) {
            break;
        }
        where_predicate(p);
        if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ {
            p.expect(COMMA);
        }
    }
    m.complete(p, WHERE_CLAUSE);
}

fn where_predicate(p: &mut Parser) {
    let m = p.start();
    match p.current() {
        LIFETIME => {
            p.bump();
            if p.at(COLON) {
                lifetime_bounds(p);
            } else {
                p.error("expected colon");
            }
        }
        _ => {
            // test where_pred_for
            // fn test<F>()
            // where
            //    for<'a> F: Fn(&'a str)
            // { }
            if p.at(FOR_KW) {
                types::for_binder(p);
            }
            if paths::is_path_start(p) || p.at(L_ANGLE) {
                types::path_type_(p, false);
            } else {
                p.error("expected a type");
            }
            if p.at(COLON) {
                bounds(p);
            } else {
                p.error("expected colon");
            }
        }
    }
    m.complete(p, WHERE_PRED);
}
<|endoftext|>


<commit_before>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::module::Module;
use self::inkwell::targets::{
    ByteOrdering, CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetData,
    TargetMachine, TargetTriple,
};
use self::inkwell::values::BasicValue;
use self::inkwell::OptimizationLevel;

fn get_native_target_machine() -> TargetMachine {
    Target::initialize_native(&InitializationConfig::default())
        .expect("Failed to initialize native target");
    let target_triple = TargetMachine::get_default_triple();
    let target = Target::from_triple(&target_triple).unwrap();
    target
        .create_target_machine(
            &target_triple,
            &TargetMachine::get_host_cpu_name().to_string(),
            &TargetMachine::get_host_cpu_features().to_string(),
            OptimizationLevel::None,
            RelocMode::Static,
            CodeModel::Small,
        )
        .unwrap()
}

#[test]
fn test_section_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_section_iterator");

    let gv_a = module.add_global(context.i8_type(), None, "a");
    gv_a.set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    gv_a.set_section("A");

    let gv_b = module.add_global(context.i16_type(), None, "b");
    gv_b.set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    gv_b.set_section("B");

    let gv_c = module.add_global(context.i32_type(), None, "c");
    gv_c.set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    gv_c.set_section("C");

    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_section_a = false;
    let mut has_section_b = false;
    let mut has_section_c = false;
    for (i, section) in object_file.get_sections().enumerate() {
        // TODO: the first section has no name, skip it.
        if i == 0 {
            continue;
        }
        match section.get_name().to_str().unwrap() {
            "A" => {
                assert!(!has_section_a);
                has_section_a = true;
                assert_eq!(section.size(), 1);
            }
            "B" => {
                assert!(!has_section_b);
                has_section_b = true;
                assert_eq!(section.size(), 2);
            }
            "C" => {
                assert!(!has_section_c);
                has_section_c = true;
                assert_eq!(section.size(), 4);
            }
            _ => {}
        }
    }
    assert!(has_section_a);
    assert!(has_section_b);
    assert!(has_section_c);
}

#[test]
fn test_symbol_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_symbol_iterator");
    module
        .add_global(context.i8_type(), None, "a")
        .set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i16_type(), None, "b")
        .set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i32_type(), None, "c")
        .set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_symbol_a = false;
    let mut has_symbol_b = false;
    let mut has_symbol_c = false;
    for symbol in object_file.get_symbols() {
        match symbol.get_name().to_str().unwrap() {
            "a" => {
                assert!(!has_symbol_a);
                has_symbol_a = true;
                assert_eq!(symbol.size(), 1);
            }
            "b" => {
                assert!(!has_symbol_b);
                has_symbol_b = true;
                assert_eq!(symbol.size(), 2);
            }
            "c" => {
                assert!(!has_symbol_c);
                has_symbol_c = true;
                assert_eq!(symbol.size(), 4);
            }
            _ => {}
        }
    }
    assert!(has_symbol_a);
    assert!(has_symbol_b);
    assert!(has_symbol_c);
}

#[test]
fn test_reloc_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let target_data = target_machine.get_target_data();
    let intptr_t = target_data.ptr_sized_int_type_in_context(&context, None);

    let mut module = context.create_module("test_reloc_iterator");
    let x_ptr = module
        .add_global(context.i8_type(), None, "x")
        .as_pointer_value();
    let x_plus_4 = x_ptr
        .const_to_int(intptr_t)
        .const_add(intptr_t.const_int(4, false));
    module
        .add_global(intptr_t, None, "a")
        .set_initializer(&x_plus_4);

    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut found_relocation = false;
    for section in object_file.get_sections() {
        for _ in section.get_relocations() {
            found_relocation = true;
            // We don't stop the traversal here, so as to exercise the iterators.
        }
    }
    assert!(found_relocation);
}
<commit_msg>Update for API change in #175.<commit_after>extern crate inkwell;

use self::inkwell::context::Context;
use self::inkwell::targets::{
    CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine,
};
use self::inkwell::values::BasicValue;
use self::inkwell::OptimizationLevel;

fn get_native_target_machine() -> TargetMachine {
    Target::initialize_native(&InitializationConfig::default())
        .expect("Failed to initialize native target");
    let target_triple = TargetMachine::get_default_triple();
    let target = Target::from_triple(&target_triple).unwrap();
    target
        .create_target_machine(
            &target_triple,
            &TargetMachine::get_host_cpu_name().to_string(),
            &TargetMachine::get_host_cpu_features().to_string(),
            OptimizationLevel::None,
            RelocMode::Static,
            CodeModel::Small,
        )
        .unwrap()
}

#[test]
fn test_section_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_section_iterator");

    let gv_a = module.add_global(context.i8_type(), None, "a");
    gv_a.set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    gv_a.set_section("A");

    let gv_b = module.add_global(context.i16_type(), None, "b");
    gv_b.set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    gv_b.set_section("B");

    let gv_c = module.add_global(context.i32_type(), None, "c");
    gv_c.set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    gv_c.set_section("C");

    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_section_a = false;
    let mut has_section_b = false;
    let mut has_section_c = false;
    for section in object_file.get_sections() {
        if let Some(name) = section.get_name() {
            match name.to_str().unwrap() {
                "A" => {
                    assert!(!has_section_a);
                    has_section_a = true;
                    assert_eq!(section.size(), 1);
                }
                "B" => {
                    assert!(!has_section_b);
                    has_section_b = true;
                    assert_eq!(section.size(), 2);
                }
                "C" => {
                    assert!(!has_section_c);
                    has_section_c = true;
                    assert_eq!(section.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_section_a);
    assert!(has_section_b);
    assert!(has_section_c);
}

#[test]
fn test_symbol_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let mut module = context.create_module("test_symbol_iterator");
    module
        .add_global(context.i8_type(), None, "a")
        .set_initializer(&context.i8_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i16_type(), None, "b")
        .set_initializer(&context.i16_type().const_zero().as_basic_value_enum());
    module
        .add_global(context.i32_type(), None, "c")
        .set_initializer(&context.i32_type().const_zero().as_basic_value_enum());
    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut has_symbol_a = false;
    let mut has_symbol_b = false;
    let mut has_symbol_c = false;
    for symbol in object_file.get_symbols() {
        if let Some(name) = symbol.get_name() {
            match name.to_str().unwrap() {
                "a" => {
                    assert!(!has_symbol_a);
                    has_symbol_a = true;
                    assert_eq!(symbol.size(), 1);
                }
                "b" => {
                    assert!(!has_symbol_b);
                    has_symbol_b = true;
                    assert_eq!(symbol.size(), 2);
                }
                "c" => {
                    assert!(!has_symbol_c);
                    has_symbol_c = true;
                    assert_eq!(symbol.size(), 4);
                }
                _ => {}
            }
        }
    }
    assert!(has_symbol_a);
    assert!(has_symbol_b);
    assert!(has_symbol_c);
}

#[test]
fn test_reloc_iterator() {
    let target_machine = get_native_target_machine();

    let context = Context::create();
    let target_data = target_machine.get_target_data();
    let intptr_t = target_data.ptr_sized_int_type_in_context(&context, None);

    let mut module = context.create_module("test_reloc_iterator");
    let x_ptr = module
        .add_global(context.i8_type(), None, "x")
        .as_pointer_value();
    let x_plus_4 = x_ptr
        .const_to_int(intptr_t)
        .const_add(intptr_t.const_int(4, false));
    module
        .add_global(intptr_t, None, "a")
        .set_initializer(&x_plus_4);

    module.set_triple(&target_machine.get_triple());
    module.set_data_layout(&target_machine.get_target_data().get_data_layout());

    let memory_buffer = target_machine
        .write_to_memory_buffer(&mut module, FileType::Object)
        .unwrap();
    let object_file = memory_buffer.create_object_file().unwrap();

    let mut found_relocation = false;
    for section in object_file.get_sections() {
        for _ in section.get_relocations() {
            found_relocation = true;
            // We don't stop the traversal here, so as to exercise the iterators.
        }
    }
    assert!(found_relocation);
}
<|endoftext|>


<commit_before>#![feature(plugin)]

#![plugin(clippy)]
#![deny(clippy)]

pub fn test(foo: Box<Vec<bool>>) { //~ ERROR You seem to be trying to use Box<Vec<T>>
    println!("{:?}", foo.get(0))
}

fn main(){
    test(Box::new(Vec::new()));
}<commit_msg>added test for issue #31<commit_after>#![feature(plugin)]

#![plugin(clippy)]
#![deny(clippy)]

pub fn test(foo: Box<Vec<bool>>) { //~ ERROR You seem to be trying to use Box<Vec<T>>
    println!("{:?}", foo.get(0))
}

pub fn test2(foo: Box<Fn(Vec<u32>)>) { // pass if #31 is fixed
	foo(vec![1, 2, 3])
}

fn main(){
    test(Box::new(Vec::new()));
    test2(Box::new(|v| println!("{:?}", v)));
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate wasm_bindgen;
extern crate wasm_bindgen_test;

use rand::rngs::StdRng;
use rand::Rng;
use rand::SeedableRng;
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*;

#[wasm_bindgen]
pub fn generate_from_seed(seed: u32) -> u32 {
    StdRng::seed_from_u64(seed as u64).gen()
}

pub mod tests {
    use super::*;

    #[wasm_bindgen_test]
    fn generate_from_seed_test() {
        let _ = generate_from_seed(42);
    }
}
<commit_msg>Minor refactor of wasm bindgen test<commit_after>extern crate rand;
extern crate wasm_bindgen;
extern crate wasm_bindgen_test;

use rand::rngs::StdRng;
use rand::Rng;
use rand::SeedableRng;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn generate_from_seed(seed: u32) -> u32 {
    StdRng::seed_from_u64(seed as u64).gen()
}

pub mod tests {
    use wasm_bindgen_test::*;

    #[wasm_bindgen_test]
    fn generate_from_seed() {
        let _ = super::generate_from_seed(42);
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::io::{stderr, Read, Write};
use std::net::TcpStream;
use std::process;
use std::str;

fn main() {
    if let Some(url) = env::args().nth(1) {
        let (scheme, reference) = url.split_at(url.find(':').unwrap_or(0));
        if scheme == "http" {
            let mut parts = reference.split('/').skip(2); //skip first two slashes
            let remote = parts.next().unwrap_or("");
            let mut path = parts.next().unwrap_or("").to_string();
            for part in parts {
                path.push('/');
                path.push_str(part);
            }

            write!(stderr(), "* Connecting to {}\n", remote).unwrap();

            let mut stream = TcpStream::connect(&remote).unwrap();

            write!(stderr(), "* Requesting {}\n", path).unwrap();

            let request = format!("GET /{} HTTP/1.0\r\n\r\n", path);
            stream.write(request.as_bytes()).unwrap();
            stream.flush().unwrap();

            write!(stderr(), "* Waiting for response\n").unwrap();

            let mut response = Vec::new();
            let count = stream.read_to_end(&mut response).unwrap();

            let mut headers = true;
            for line in unsafe { str::from_utf8_unchecked(&response[.. count]) }.lines() {
                if headers {
                    if line.is_empty() {
                        headers = false;
                    } else {
                        write!(stderr(), "> {}\n", line).unwrap();
                    }
                } else {
                    println!("{}", line);
                }
            }
        } else {
            write!(stderr(), "wget: unknown scheme '{}'\n", scheme).unwrap();
            process::exit(1);
        }
    } else {
        write!(stderr(), "wget: http://host:port/path\n").unwrap();
        process::exit(1);
    }
}
<commit_msg>Send host header with wget<commit_after>use std::env;
use std::io::{stderr, Read, Write};
use std::net::TcpStream;
use std::process;
use std::str;

fn main() {
    if let Some(url) = env::args().nth(1) {
        let (scheme, reference) = url.split_at(url.find(':').unwrap_or(0));
        if scheme == "http" {
            let mut parts = reference.split('/').skip(2); //skip first two slashes
            let remote = parts.next().unwrap_or("");
            let mut path = parts.next().unwrap_or("").to_string();
            for part in parts {
                path.push('/');
                path.push_str(part);
            }

            write!(stderr(), "* Connecting to {}\n", remote).unwrap();

            let mut stream = TcpStream::connect(&remote).unwrap();

            write!(stderr(), "* Requesting {}\n", path).unwrap();

            let request = format!("GET /{} HTTP/1.1\r\nHost: {}\r\n\r\n", path, env::args().nth(2).unwrap_or(remote.to_string()));
            stream.write(request.as_bytes()).unwrap();
            stream.flush().unwrap();

            write!(stderr(), "* Waiting for response\n").unwrap();

            let mut response = [0; 65536];
            let count = stream.read(&mut response).unwrap();

            let mut headers = true;
            for line in unsafe { str::from_utf8_unchecked(&response[.. count]) }.lines() {
                if headers {
                    if line.is_empty() {
                        headers = false;
                    } else {
                        write!(stderr(), "> {}\n", line).unwrap();
                    }
                } else {
                    println!("{}", line);
                }
            }
        } else {
            write!(stderr(), "wget: unknown scheme '{}'\n", scheme).unwrap();
            process::exit(1);
        }
    } else {
        write!(stderr(), "wget: http://host:port/path\n").unwrap();
        process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate graphics;
extern crate freetype as ft;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate piston;

use std::cell::RefCell;
use std::path::Path;
use sdl2_window::Sdl2Window;
use opengl_graphics::{
    Gl,
    Texture,
    OpenGL
};
use graphics::vecmath::Matrix2d;
use graphics::{
    default_draw_state,
    Image,
    RelativeTransform,
    color
};
use piston::window::WindowSettings;
use piston::event::Event;

fn render_text(face: &mut ft::Face, gl: &mut Gl, t: Matrix2d, text: &str) {
    let mut x = 0;
    let mut y = 0;
    for ch in text.chars() {
        face.load_char(ch as usize, ft::face::RENDER).unwrap();
        let g = face.glyph();

        let bitmap = g.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        Image::colored(color::BLACK).draw(
            &texture,
            default_draw_state(),
            t.trans((x + g.bitmap_left()) as f64, (y - g.bitmap_top()) as f64),
            gl
        );

        x += (g.advance().x >> 6) as i32;
        y += (g.advance().y >> 6) as i32;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Font with Piston".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let freetype = ft::Library::init().unwrap();
    let font = Path::new("./examples/assets/FiraSans-Regular.ttf");
    let mut face = freetype.new_face(&font, 0).unwrap();
    face.set_pixel_sizes(0, 48).unwrap();

    let ref mut gl = Gl::new(opengl);

    let window = RefCell::new(window);
    for e in piston::events(&window) {
        match e {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                    let transform = c.transform.trans(0.0, 100.0);

                    graphics::clear(color::WHITE, gl);
                    render_text(&mut face, gl, transform, "Hello Piston!");
                });
            },
            _ => ()
        }
    }
}

<commit_msg>Upgraded to latest event_loop<commit_after>extern crate graphics;
extern crate freetype as ft;
extern crate sdl2_window;
extern crate opengl_graphics;
extern crate piston;

use std::rc::Rc;
use std::cell::RefCell;
use std::path::Path;
use sdl2_window::Sdl2Window;
use opengl_graphics::{
    Gl,
    Texture,
    OpenGL
};
use graphics::vecmath::Matrix2d;
use graphics::{
    default_draw_state,
    Image,
    RelativeTransform,
    color
};
use piston::window::WindowSettings;
use piston::event::Event;

fn render_text(face: &mut ft::Face, gl: &mut Gl, t: Matrix2d, text: &str) {
    let mut x = 0;
    let mut y = 0;
    for ch in text.chars() {
        face.load_char(ch as usize, ft::face::RENDER).unwrap();
        let g = face.glyph();

        let bitmap = g.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        Image::colored(color::BLACK).draw(
            &texture,
            default_draw_state(),
            t.trans((x + g.bitmap_left()) as f64, (y - g.bitmap_top()) as f64),
            gl
        );

        x += (g.advance().x >> 6) as i32;
        y += (g.advance().y >> 6) as i32;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: "Font with Piston".to_string(),
            size: [300, 300],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let freetype = ft::Library::init().unwrap();
    let font = Path::new("./examples/assets/FiraSans-Regular.ttf");
    let mut face = freetype.new_face(&font, 0).unwrap();
    face.set_pixel_sizes(0, 48).unwrap();

    let ref mut gl = Gl::new(opengl);

    let window = Rc::new(RefCell::new(window));
    for e in piston::events(window) {
        match e {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                    let transform = c.transform.trans(0.0, 100.0);

                    graphics::clear(color::WHITE, gl);
                    render_text(&mut face, gl, transform, "Hello Piston!");
                });
            },
            _ => ()
        }
    }
}

<|endoftext|>


<commit_before>use crate::nodes::*;

pub fn depused(m: &Module, dep: &Module) -> bool {
    let exports = get_exports(dep);
    let mut list: Vec<String> = Vec::new();
    for x in exports.consts {
        list.push(x.id);
    }
    for x in exports.fns {
        list.push(x.form.name);
    }
    for x in exports.types {
        match x.type_name {
            TypedefTarget::Typename(t) => {
                list.push(t.name);
            }
            TypedefTarget::AnonymousStruct { .. } => {}
        }
    }
    for obj in &m.elements {
        match obj {
            ModuleObject::CompatMacro(_) => {}
            ModuleObject::Import { .. } => {}
            ModuleObject::Enum(x) => {
                for m in &x.members {
                    match &m.value {
                        Some(e) => {
                            if used_in_expr(e, &list) {
                                return true;
                            }
                        }
                        None => {}
                    }
                }
            }
            ModuleObject::Typedef(x) => match &x.type_name {
                TypedefTarget::AnonymousStruct { .. } => {}
                TypedefTarget::Typename(t) => {
                    if has(&t.name, &list) {
                        return true;
                    }
                }
            },
            ModuleObject::ModuleVariable(x) => {
                if has(&x.type_name.name, &list) || used_in_expr(&x.value, &list) {
                    return true;
                }
            }
            ModuleObject::FunctionDeclaration(x) => {
                if has(&x.type_name.name, &list) {
                    return true;
                }
                for p in &x.parameters.list {
                    if has(&p.type_name.name, &list) {
                        return true;
                    }
                }
                if used_in_body(&x.body, &list) {
                    return true;
                }
            }
        }
    }
    return false;
}

fn used_in_expr(e: &Expression, list: &Vec<String>) -> bool {
    match e {
        Expression::Literal(_) => false,
        Expression::StructLiteral { members } => {
            for m in members {
                if used_in_expr(&m.value, list) {
                    return true;
                }
            }
            return false;
        }
        Expression::ArrayLiteral(x) => used_in_array_literal(x, list),
        Expression::Identifier(x) => has(x, list),
        Expression::BinaryOp { op: _, a, b } => used_in_expr(a, list) || used_in_expr(b, list),
        Expression::PrefixOperator {
            operator: _,
            operand,
        } => used_in_expr(operand, list),
        Expression::PostfixOperator {
            operand,
            operator: _,
        } => used_in_expr(operand, list),
        Expression::Cast { type_name, operand } => {
            has(&type_name.type_name.name, list) || used_in_expr(operand, list)
        }
        Expression::FunctionCall {
            function,
            arguments,
        } => {
            if used_in_expr(function, list) {
                return true;
            }
            for a in arguments {
                if used_in_expr(a, list) {
                    return true;
                }
            }
            return false;
        }
        Expression::Sizeof { argument } => match &**argument {
            SizeofArgument::Expression(e) => used_in_expr(e, list),
            SizeofArgument::Typename(t) => has(&t.name, list),
        },
        Expression::ArrayIndex { array, index } => {
            used_in_expr(array, list) || used_in_expr(index, list)
        }
    }
}

fn used_in_array_literal(x: &ArrayLiteral, list: &Vec<String>) -> bool {
    for e in &x.values {
        match &e.index {
            ArrayLiteralKey::None => {}
            ArrayLiteralKey::Literal(_) => {}
            ArrayLiteralKey::Identifier(s) => {
                if has(&s, list) {
                    return true;
                }
            }
        }
        match &e.value {
            ArrayLiteralValue::Literal(_) => {}
            ArrayLiteralValue::Identifier(s) => {
                if has(&s, list) {
                    return true;
                }
            }
            ArrayLiteralValue::ArrayLiteral(a) => {
                if used_in_array_literal(&a, list) {
                    return true;
                }
            }
        }
    }
    return false;
}

fn has(name: &String, list: &Vec<String>) -> bool {
    return list.contains(name);
}

fn used_in_body(body: &Body, list: &Vec<String>) -> bool {
    for s in &body.statements {
        match s {
            Statement::VariableDeclaration {
                type_name,
                forms: _,
                values,
            } => {
                if has(&type_name.name, list) {
                    return true;
                }
                for v in values {
                    match v {
                        Some(e) => {
                            if used_in_expr(&e, list) {
                                return true;
                            }
                        }
                        None => {}
                    }
                }
            }
            Statement::If {
                condition,
                body,
                else_body,
            } => {
                if used_in_expr(&condition, list) || used_in_body(&body, list) {
                    return true;
                }
                match else_body {
                    Some(e) => {
                        if used_in_body(&e, list) {
                            return true;
                        }
                    }
                    None => {}
                }
            }
            Statement::For {
                init,
                condition,
                action,
                body,
            } => {
                if used_in_expr(&condition, list)
                    || used_in_expr(&action, list)
                    || used_in_body(&body, list)
                {
                    return true;
                }
                match init {
                    ForInit::Expression(e) => {
                        if used_in_expr(e, list) {
                            return true;
                        }
                    }
                    ForInit::LoopCounterDeclaration {
                        type_name,
                        value,
                        form: _,
                    } => {
                        if used_in_expr(&value, list) {
                            return true;
                        }
                        if has(&type_name.name, list) {
                            return true;
                        }
                    }
                }
            }
            Statement::While { condition, body } => {
                if used_in_expr(&condition, list) || used_in_body(&body, list) {
                    return true;
                }
            }
            Statement::Return { expression } => match expression {
                Some(e) => {
                    if used_in_expr(&e, list) {
                        return true;
                    }
                }
                None => {}
            },
            Statement::Switch {
                value,
                cases,
                default,
            } => {
                if used_in_expr(&value, list) {
                    return true;
                }
                match default {
                    Some(d) => {
                        if used_in_body(&d, list) {
                            return true;
                        }
                    }
                    None => {}
                }
                for c in cases {
                    match &c.value {
                        SwitchCaseValue::Identifier(x) => {
                            if has(&x, list) {
                                return true;
                            }
                        }
                        SwitchCaseValue::Literal(_) => {}
                    }
                }
            }
            Statement::Expression(x) => {
                if used_in_expr(&x, list) {
                    return true;
                }
            }
        }
    }
    return false;
}

pub struct Exports {
    pub consts: Vec<EnumItem>,
    pub fns: Vec<FunctionDeclaration>,
    pub types: Vec<Typedef>,
}

pub fn get_exports(m: &Module) -> Exports {
    let mut exports = Exports {
        consts: Vec::new(),
        fns: Vec::new(),
        types: Vec::new(),
    };
    for e in &m.elements {
        match e {
            ModuleObject::Enum(x) => {
                if x.is_pub {
                    for member in &x.members {
                        exports.consts.push(member.clone());
                    }
                }
            }
            ModuleObject::Typedef(x) => {
                if x.is_pub {
                    exports.types.push(x.clone());
                }
            }
            ModuleObject::FunctionDeclaration(f) => {
                if f.is_pub {
                    exports.fns.push(f.clone())
                }
            }
            _ => {}
        }
    }
    return exports;
}
<commit_msg>Add typedef to usage checker<commit_after>use crate::nodes::*;

pub fn depused(m: &Module, dep: &Module) -> bool {
    let exports = get_exports(dep);
    let mut list: Vec<String> = Vec::new();
    for x in exports.consts {
        list.push(x.id);
    }
    for x in exports.fns {
        list.push(x.form.name);
    }
    for x in exports.types {
        match x.type_name {
            TypedefTarget::Typename(t) => {
                list.push(t.name);
            }
            TypedefTarget::AnonymousStruct { .. } => list.push(x.form.alias),
        }
    }
    for obj in &m.elements {
        match obj {
            ModuleObject::CompatMacro(_) => {}
            ModuleObject::Import { .. } => {}
            ModuleObject::Enum(x) => {
                for m in &x.members {
                    match &m.value {
                        Some(e) => {
                            if used_in_expr(e, &list) {
                                return true;
                            }
                        }
                        None => {}
                    }
                }
            }
            ModuleObject::Typedef(x) => match &x.type_name {
                TypedefTarget::AnonymousStruct { .. } => {}
                TypedefTarget::Typename(t) => {
                    if has(&t.name, &list) {
                        return true;
                    }
                }
            },
            ModuleObject::ModuleVariable(x) => {
                if has(&x.type_name.name, &list) || used_in_expr(&x.value, &list) {
                    return true;
                }
            }
            ModuleObject::FunctionDeclaration(x) => {
                if has(&x.type_name.name, &list) {
                    return true;
                }
                for p in &x.parameters.list {
                    if has(&p.type_name.name, &list) {
                        return true;
                    }
                }
                if used_in_body(&x.body, &list) {
                    return true;
                }
            }
        }
    }
    return false;
}

fn used_in_expr(e: &Expression, list: &Vec<String>) -> bool {
    match e {
        Expression::Literal(_) => false,
        Expression::StructLiteral { members } => {
            for m in members {
                if used_in_expr(&m.value, list) {
                    return true;
                }
            }
            return false;
        }
        Expression::ArrayLiteral(x) => used_in_array_literal(x, list),
        Expression::Identifier(x) => has(x, list),
        Expression::BinaryOp { op: _, a, b } => used_in_expr(a, list) || used_in_expr(b, list),
        Expression::PrefixOperator {
            operator: _,
            operand,
        } => used_in_expr(operand, list),
        Expression::PostfixOperator {
            operand,
            operator: _,
        } => used_in_expr(operand, list),
        Expression::Cast { type_name, operand } => {
            has(&type_name.type_name.name, list) || used_in_expr(operand, list)
        }
        Expression::FunctionCall {
            function,
            arguments,
        } => {
            if used_in_expr(function, list) {
                return true;
            }
            for a in arguments {
                if used_in_expr(a, list) {
                    return true;
                }
            }
            return false;
        }
        Expression::Sizeof { argument } => match &**argument {
            SizeofArgument::Expression(e) => used_in_expr(e, list),
            SizeofArgument::Typename(t) => has(&t.name, list),
        },
        Expression::ArrayIndex { array, index } => {
            used_in_expr(array, list) || used_in_expr(index, list)
        }
    }
}

fn used_in_array_literal(x: &ArrayLiteral, list: &Vec<String>) -> bool {
    for e in &x.values {
        match &e.index {
            ArrayLiteralKey::None => {}
            ArrayLiteralKey::Literal(_) => {}
            ArrayLiteralKey::Identifier(s) => {
                if has(&s, list) {
                    return true;
                }
            }
        }
        match &e.value {
            ArrayLiteralValue::Literal(_) => {}
            ArrayLiteralValue::Identifier(s) => {
                if has(&s, list) {
                    return true;
                }
            }
            ArrayLiteralValue::ArrayLiteral(a) => {
                if used_in_array_literal(&a, list) {
                    return true;
                }
            }
        }
    }
    return false;
}

fn has(name: &String, list: &Vec<String>) -> bool {
    return list.contains(name);
}

fn used_in_body(body: &Body, list: &Vec<String>) -> bool {
    for s in &body.statements {
        match s {
            Statement::VariableDeclaration {
                type_name,
                forms: _,
                values,
            } => {
                if has(&type_name.name, list) {
                    return true;
                }
                for v in values {
                    match v {
                        Some(e) => {
                            if used_in_expr(&e, list) {
                                return true;
                            }
                        }
                        None => {}
                    }
                }
            }
            Statement::If {
                condition,
                body,
                else_body,
            } => {
                if used_in_expr(&condition, list) || used_in_body(&body, list) {
                    return true;
                }
                match else_body {
                    Some(e) => {
                        if used_in_body(&e, list) {
                            return true;
                        }
                    }
                    None => {}
                }
            }
            Statement::For {
                init,
                condition,
                action,
                body,
            } => {
                if used_in_expr(&condition, list)
                    || used_in_expr(&action, list)
                    || used_in_body(&body, list)
                {
                    return true;
                }
                match init {
                    ForInit::Expression(e) => {
                        if used_in_expr(e, list) {
                            return true;
                        }
                    }
                    ForInit::LoopCounterDeclaration {
                        type_name,
                        value,
                        form: _,
                    } => {
                        if used_in_expr(&value, list) {
                            return true;
                        }
                        if has(&type_name.name, list) {
                            return true;
                        }
                    }
                }
            }
            Statement::While { condition, body } => {
                if used_in_expr(&condition, list) || used_in_body(&body, list) {
                    return true;
                }
            }
            Statement::Return { expression } => match expression {
                Some(e) => {
                    if used_in_expr(&e, list) {
                        return true;
                    }
                }
                None => {}
            },
            Statement::Switch {
                value,
                cases,
                default,
            } => {
                if used_in_expr(&value, list) {
                    return true;
                }
                match default {
                    Some(d) => {
                        if used_in_body(&d, list) {
                            return true;
                        }
                    }
                    None => {}
                }
                for c in cases {
                    match &c.value {
                        SwitchCaseValue::Identifier(x) => {
                            if has(&x, list) {
                                return true;
                            }
                        }
                        SwitchCaseValue::Literal(_) => {}
                    }
                }
            }
            Statement::Expression(x) => {
                if used_in_expr(&x, list) {
                    return true;
                }
            }
        }
    }
    return false;
}

pub struct Exports {
    pub consts: Vec<EnumItem>,
    pub fns: Vec<FunctionDeclaration>,
    pub types: Vec<Typedef>,
}

pub fn get_exports(m: &Module) -> Exports {
    let mut exports = Exports {
        consts: Vec::new(),
        fns: Vec::new(),
        types: Vec::new(),
    };
    for e in &m.elements {
        match e {
            ModuleObject::Enum(x) => {
                if x.is_pub {
                    for member in &x.members {
                        exports.consts.push(member.clone());
                    }
                }
            }
            ModuleObject::Typedef(x) => {
                if x.is_pub {
                    exports.types.push(x.clone());
                }
            }
            ModuleObject::FunctionDeclaration(f) => {
                if f.is_pub {
                    exports.fns.push(f.clone())
                }
            }
            _ => {}
        }
    }
    return exports;
}
<|endoftext|>


<commit_before>use std::io::Error;

// Parsing command line arguments from singe line.
// See also: http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
pub fn parse(cmd: &str) -> Result<Vec<String>, Error> {
	let mut args: Vec<String> = Vec::new();
	let mut arg: String = String::new();
	let mut slash: usize = 0;
	let mut quote = false;
	let mut data = false;
	for c in cmd.chars() {
		match c {
			' ' | '\t' => {
				arg = add_slashes(arg, if quote && ((slash % 2) == 0) {slash / 2} else {slash});
				slash = 0;
				if quote {
					arg.push(c);
					data = true;
				} else if data {
					args.push(arg);
					arg = String::new();
					data = false;
				}
			}
			'\\' => {
				slash = slash + 1;
				data = true;
			}
			'"' => {
				arg = add_slashes(arg, slash / 2);
				if (slash & 2) == 0 {
					quote = !quote;
				} else {
					arg.push(c);
				}
				slash = 0;
				data = true;
			}
			_ => {
				arg = add_slashes(arg, if quote && ((slash % 2) == 0) {slash / 2} else {slash});
				slash = 0;
				arg.push(c);
				data = true;
			}
		}
	}
	arg = add_slashes(arg, if quote && ((slash % 2) == 0) {slash / 2} else {slash});
	if data {
		args.push(arg);
	}
	return Ok(args);
}

fn add_slashes(mut line: String, count: usize) -> String {
	for _ in 0..count {
		line.push('\\');
	}
	line
}

#[test]
fn test_parse_1() {
	assert_eq!(parse("\"abc\" d e").unwrap(), ["abc", "d", "e"]);
}

#[test]
fn test_parse_2() {
	assert_eq!(parse(" \"abc\" d e ").unwrap(), ["abc", "d", "e"]);
}

#[test]
fn test_parse_3() {
	assert_eq!(parse("\"\" \"abc\" d e \"\"").unwrap(), ["", "abc", "d", "e", ""]);
}

#[test]
fn test_parse_4() {
	assert_eq!(parse("a\\\\b d\"e f\"g h").unwrap(), ["a\\\\b", "de fg", "h"]);
}

#[test]
fn test_parse_5() {
	assert_eq!(parse("a\\\\\\\"b c d").unwrap(), ["a\\\"b", "c", "d"]);
}

#[test]
fn test_parse_6() {
	assert_eq!(parse("a\\\\\\\\\"b c\" d e").unwrap(), ["a\\\\b c", "d", "e"]);
}

#[test]
fn test_parse_7() {
	assert_eq!(parse("C:\\Windows\\System32 d e").unwrap(), ["C:\\Windows\\System32", "d", "e"]);
}

#[test]
fn test_parse_8() {
	assert_eq!(parse("/TEST\"C:\\Windows\\System32\" d e").unwrap(), ["/TESTC:\\Windows\\System32", "d", "e"]);
}
<commit_msg>Linux: now can build Unreal Engine, but without any profit<commit_after>use std::io::{Error, ErrorKind};

#[derive(PartialEq)]
enum Quote {
	None,
	Double,
	Single,
}

// Parsing command line arguments from singe line.
pub fn parse(cmd: &str) -> Result<Vec<String>, Error> {
	let mut args: Vec<String> = Vec::new();
	let mut arg: String = String::new();
	let mut slash: bool = false;
	let mut quote = Quote::None;
	let mut data = false;
	for c in cmd.chars() {
		match c {
			'\'' if quote == Quote::Single => {
				quote = Quote::None;
			}
			_ if quote == Quote::Single => {
				arg.push(c);
			}
			' ' | '\t' | '"' | '\'' | '\\' if slash => {
				arg.push(c);
				slash = false;
			}
			_ if slash => {
				arg.push('\\');
				arg.push(c);
				slash = false;
			}
			'"' if quote == Quote::Double => {
				quote = Quote::None;
			}
			' ' | '\t' if quote == Quote::None => {
				if data {
					args.push(arg);
					arg = String::new();
					data = false;
				}
			}
			'\\' => {
				slash = true;
				data = true;
			}
			'"' => {
				quote = Quote::Double;
				data = true;
			}
			'\'' => {
				quote = Quote::Single;
				data = true;
			}
			_ => {
				arg.push(c);
				data = true;
			}
		}
	}
	if data {
		args.push(arg);
	}
	if slash {
		return Err(Error::new(ErrorKind::InvalidInput, "Unexpected line end: escape sequence is not finished"));
	}
	match quote {
	    Quote::Single => Err(Error::new(ErrorKind::InvalidInput, "Unexpected line end: single quote is not closed")),
	    Quote::Double => Err(Error::new(ErrorKind::InvalidInput, "Unexpected line end: double quote is not closed")),
	    Quote::None => Ok(args),
	}
}

#[test]
fn test_parse_1() {
	assert_eq!(parse("\"abc\" d e").unwrap(), ["abc", "d", "e"]);
}

#[test]
fn test_parse_2() {
	assert_eq!(parse(" \"abc\" d e ").unwrap(), ["abc", "d", "e"]);
}

#[test]
fn test_parse_3() {
	assert_eq!(parse("\"\" \"abc\" d e \"\"").unwrap(), ["", "abc", "d", "e", ""]);
}

#[test]
fn test_parse_4() {
	assert_eq!(parse("a\\\\b d\"e f\"g h").unwrap(), ["a\\b", "de fg", "h"]);
}

#[test]
fn test_parse_5() {
	assert_eq!(parse("a\\\\\\\"b c d").unwrap(), ["a\\\"b", "c", "d"]);
}

#[test]
fn test_parse_6() {
	assert_eq!(parse("a\\\\\\\\\"b c\" d e").unwrap(), ["a\\\\b c", "d", "e"]);
}

#[test]
fn test_parse_7() {
	assert_eq!(parse("C:\\Windows\\System32 d e").unwrap(), ["C:\\Windows\\System32", "d", "e"]);
}

#[test]
fn test_parse_8() {
	assert_eq!(parse("/TEST\"C:\\Windows\\System32\" d e").unwrap(), ["/TESTC:\\Windows\\System32", "d", "e"]);
}

#[test]
fn test_parse_9() {
	assert_eq!(parse("begin ' some text \" foo\\ bar\\' end").unwrap(), ["begin", " some text \" foo\\ bar\\", "end"]);
}

#[test]
fn test_parse_10() {
	assert_eq!(parse("begin some\\ text end").unwrap(), ["begin", "some text", "end"]);
}
<|endoftext|>


<commit_before>trait InDays {
  fn in_days(self) -> String;
}

impl InDays for i32 {
   fn in_days(self) -> String {
       if self > 1 {
           format!("{} days", self.to_string())
       } else {
           format!("{} day", self.to_string())
       }
   }
}

fn main() {
    println!("{}", 5.in_days());
    println!("{}", 1.in_days());
}
<commit_msg>examples: better monkey patch example<commit_after>trait IsOdd {
  fn is_odd(self) -> bool;
}

impl IsOdd for i32 {
   fn is_odd(self) -> bool {
       self % 2 == 0
   }
}

fn main() {
    println!("5 is odd: {}", 5.is_odd());
    println!("2 is odd: {}", 2.is_odd());
}
<|endoftext|>


<commit_before>use std::time;
use std::fmt;
use std::ops;
use std::convert;

use chrono;

use super::error;
use super::error::DurationError;

pub const SECS_PER_DAY: f64 = 60.0*60.0*24.0;
pub const SECS_PER_HOUR: f64 = 60.0*60.0;
pub const SECS_PER_MINUTE: f64 = 60.0;

pub trait TimePoint<Rhs=Self> {
    fn duration_between(&self, rhs: &Rhs) -> FloatDuration;
}

#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct FloatDuration {
    secs: f64,
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct DecomposedTime {
    pub days: u32,
    pub hours: u32,
    pub minutes: u32,
    pub seconds: u32,
    pub fractional_seconds: f64,
    pub sign: i8,
}

impl FloatDuration {
    pub fn new(secs: f64) -> FloatDuration {
        FloatDuration {secs}
    }

    pub fn days(days: f64) -> FloatDuration {
        FloatDuration {secs: days * (3600.0 * 24.0)}
    }
    pub fn hours(hours: f64) -> FloatDuration {
        FloatDuration {secs: hours * 3600.0}
    }
    pub fn minutes(mins: f64) -> FloatDuration {
        FloatDuration {secs: mins * 60.0}
    }
    pub fn seconds(secs: f64) -> FloatDuration {
        FloatDuration {secs}
    }
    pub fn milliseconds(millis: f64) -> FloatDuration {
        FloatDuration {secs: millis / 1000.0}
    }
    pub fn microseconds(micros: f64) -> FloatDuration {
        FloatDuration {secs: micros / 1.0e6}
    }
    pub fn nanoseconds(nanos: f64) -> FloatDuration {
        FloatDuration {secs: nanos / 1.0e9}
    }

    pub fn decompose(&self) -> DecomposedTime {
        let mut secs_left = self.secs;

        let days = (secs_left / SECS_PER_DAY).trunc();
        secs_left -= days*SECS_PER_DAY;
        let hours = (secs_left / SECS_PER_HOUR).trunc();
        secs_left -= hours*SECS_PER_HOUR;
        let minutes = (secs_left / SECS_PER_MINUTE).trunc();
        secs_left -= minutes*SECS_PER_MINUTE;
        let seconds = secs_left.trunc();
        let fract = secs_left.fract();

        DecomposedTime {
            days: days as u32,
            hours: hours as u32,
            minutes: minutes as u32,
            seconds: seconds as u32,
            fractional_seconds: fract,
            sign: self.secs.signum() as i8,
        }
    }

    pub fn as_days(&self) -> f64 {
        self.secs / SECS_PER_DAY
    }
    pub fn as_hours(&self) -> f64 {
        self.secs / SECS_PER_HOUR
    }
    pub fn as_minutes(&self) -> f64 {
        self.secs / SECS_PER_MINUTE
    }
    pub fn as_seconds(&self) -> f64 {
        self.secs
    }
    pub fn as_milliseconds(&self) -> f64 {
        self.secs * 1.0e3
    }
    pub fn as_microseconds(&self) -> f64 {
        self.secs * 1.0e6
    }
    pub fn as_nanoseconds(&self) -> f64 {
        self.secs * 1.0e9
    }

    pub fn zero() -> FloatDuration {
        FloatDuration {secs: 0.0}
    }
    pub fn is_zero(&self) -> bool {
        self.secs == 0.0
    }
    pub fn is_positive(&self) -> bool {
        self.secs.is_sign_positive()
    }
    pub fn is_negative(&self) -> bool {
        self.secs.is_sign_negative()
    }

    pub fn as_std(&self) -> error::Result<time::Duration> {
        if self.secs.is_sign_negative() {
            Err(DurationError::StdOutOfRange)
        } else {
            let seconds = self.secs.trunc();
            let nanos = self.secs.fract() * 1e9;

            Ok(time::Duration::new(seconds as u64, nanos as u32))
        }
    }

    pub fn from_std(duration: time::Duration) -> error::Result<FloatDuration> {
        Ok(FloatDuration::seconds(
            (duration.as_secs() as f64) + (duration.subsec_nanos() as f64)*1.0e-9))
    }

    pub fn from_decomposed(decomposed: &DecomposedTime) -> FloatDuration {
        let seconds = (decomposed.days as f64)*SECS_PER_DAY
            + (decomposed.hours as f64)*SECS_PER_HOUR
            + (decomposed.minutes as f64)*SECS_PER_MINUTE
            + (decomposed.seconds as f64)
            + decomposed.fractional_seconds;

        FloatDuration {
            secs: seconds
        }
    }
}

impl FloatDuration {
    pub fn as_chrono_duration(&self) -> error::Result<chrono::Duration> {
        let std_duration = self.as_std()?;
        chrono::Duration::from_std(std_duration).map_err(|e| convert::From::from(e))
    }

    pub fn from_chrono_duration(duration: &chrono::Duration)
            -> error::Result<FloatDuration>
    {
        let std_duration = duration.to_std()?;
        FloatDuration::from_std(std_duration)
    }
}

impl DecomposedTime {
    pub fn new() -> DecomposedTime {
        DecomposedTime { days: 0, hours: 0, minutes: 0, seconds: 0,
            fractional_seconds: 0.0, sign: 1 }
    }

    pub fn from_components(days: u32, hours: u32, minutes: u32,
               seconds: u32, fractional_seconds: f64) -> DecomposedTime
    {
        DecomposedTime {
            days, hours, minutes, seconds, fractional_seconds, sign: 1}
    }

    pub fn negate(mut self) -> DecomposedTime {
        self.sign *= -1;
        self
    }
}

impl fmt::Display for DecomposedTime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if self.days > 0 {
            write!(fmt, "{}d ", self.days as u64)?;
        }

        if self.sign.is_negative() {
            write!(fmt, "-")?;
        }
        write!(fmt, "{:02}:{:02}:{:02}.{}",
            self.hours,
            self.minutes,
            self.seconds,
            self.fractional_seconds)
    }
}

impl fmt::Display for FloatDuration {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if self.secs > SECS_PER_DAY {
            write!(fmt, "{} days", self.as_days())
        } else if self.secs > SECS_PER_HOUR {
            write!(fmt, "{} hours", self.as_hours())
        } else if self.secs > SECS_PER_MINUTE {
            write!(fmt, "{} minutes", self.as_minutes())
        } else if self.secs > 1.0 {
            write!(fmt, "{} seconds", self.as_seconds())
        } else if self.secs > 1.0e-3 {
            write!(fmt, "{} milliseconds", self.as_milliseconds())
        } else if self.secs > 1.0e-6 {
            write!(fmt, "{} microseconds", self.as_microseconds())
        } else {
            write!(fmt, "{} nanoseconds", self.as_nanoseconds())
        }
    }
}

impl ops::Neg for FloatDuration {
    type Output = FloatDuration;

    fn neg(self) -> FloatDuration {
        FloatDuration {secs: -self.secs}
    }
}

impl ops::Add<FloatDuration> for FloatDuration {
    type Output = FloatDuration;

    fn add(self, rhs: FloatDuration) -> FloatDuration {
        FloatDuration {secs: self.secs + rhs.secs}
    }
}
impl ops::Sub<FloatDuration> for FloatDuration {
    type Output = FloatDuration;

    fn sub(self, rhs: FloatDuration) -> FloatDuration {
        FloatDuration {secs: self.secs - rhs.secs}
    }
}

impl ops::Mul<f64> for FloatDuration {
    type Output = FloatDuration;

    fn mul(self, rhs: f64) -> FloatDuration {
        FloatDuration {secs: self.secs * rhs}
    }
}
impl ops::Div<f64> for FloatDuration {
    type Output = FloatDuration;

    fn div(self, rhs: f64) -> FloatDuration {
        FloatDuration {secs: self.secs / rhs}
    }
}

impl ops::AddAssign<FloatDuration> for FloatDuration {
    fn add_assign(&mut self, rhs: FloatDuration) {
        self.secs += rhs.secs;
    }
}
impl ops::SubAssign<FloatDuration> for FloatDuration {
    fn sub_assign(&mut self, rhs: FloatDuration) {
        self.secs -= rhs.secs;
    }
}

impl ops::MulAssign<f64> for FloatDuration {
    fn mul_assign(&mut self, rhs: f64) {
        self.secs *= rhs;
    }
}
impl ops::DivAssign<f64> for FloatDuration {
    fn div_assign(&mut self, rhs: f64) {
        self.secs /= rhs;
    }
}

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

    #[test]
    fn test_construct() {
        let duration1 = FloatDuration::hours(3.0);
        assert_eq!(duration1.as_hours(), 3.0);
        assert_eq!(duration1.as_minutes(), 180.0);
        assert_eq!(duration1.as_seconds(), 180.0*60.0);
        assert_eq!(duration1.as_days(), 3.0/24.0);
        assert_eq!(duration1.as_milliseconds(), 180.0*60.0*1000.0);

        let duration2 = FloatDuration::milliseconds(55.0);
        assert_eq!(duration2.as_seconds(), 0.055);
        assert_eq!(duration2.as_milliseconds(), 55.0);
        assert_eq!(duration2.as_microseconds(), 55000.0);
        assert_eq!(duration2.as_nanoseconds(), 55000000.0);
        assert!(!duration2.is_zero());

        let duration3 = FloatDuration::zero();
        assert!(duration3.is_zero());

        assert_eq!(FloatDuration::days(1.5), FloatDuration::hours(36.0));
        assert_eq!(FloatDuration::minutes(30.0), FloatDuration::hours(0.5));
        assert_eq!(FloatDuration::seconds(180.0), FloatDuration::minutes(3.0));
        assert_eq!(FloatDuration::seconds(3.5), FloatDuration::milliseconds(3500.0));
        assert_eq!(FloatDuration::microseconds(300.0), FloatDuration::milliseconds(0.30));
        assert_eq!(FloatDuration::nanoseconds(1000.0), FloatDuration::microseconds(1.0));
    }

    #[test]
    fn test_arithmetic() {
        let duration1 = FloatDuration::minutes(5.0) + FloatDuration::seconds(30.0);
        assert_eq!(duration1, FloatDuration::seconds(330.0));

        let duration2 = FloatDuration::hours(3.0) * 2.5;
        assert_eq!(duration2, FloatDuration::hours(7.5));

        let duration3 = FloatDuration::days(3.0) / 3.0 - FloatDuration::hours(2.0);
        assert_eq!(duration3, FloatDuration::hours(22.0));

        let duration4 = FloatDuration::zero() + FloatDuration::milliseconds(500.0)
            + FloatDuration::microseconds(500.0);
        assert_eq!(duration4, FloatDuration::microseconds(500500.0));

    }

    #[test]
    fn test_std_conversion() {
        let duration1 = FloatDuration::minutes(5.0);
        let std_duration1 = duration1.as_std().unwrap();
        assert!(duration1.is_positive());
        assert_eq!(std_duration1, time::Duration::new(300, 0));
        assert_eq!(FloatDuration::from_std(std_duration1).unwrap(), duration1);

        let duration2 = FloatDuration::hours(-2.0);
        assert!(duration2.is_negative());
        assert!(!duration2.as_std().is_ok());
        let std_duration2 = (-duration2).as_std().unwrap();
        assert_eq!(std_duration2, time::Duration::new(3600*2, 0));
        assert_eq!(FloatDuration::from_std(std_duration2).unwrap(), -duration2);
    }

    #[test]
    fn test_display() {
        use std::fmt::Write;

        let mut buffer1 = "".to_string();
        let mut buffer1_2 = "".to_string();
        let duration1 = FloatDuration::minutes(3.5);

        write!(buffer1, "{}", duration1);
        write!(buffer1_2, "{}", duration1.decompose());
        assert_eq!(buffer1, "3.5 minutes");
        assert_eq!(buffer1_2, "00:03:30.0");

        let mut buffer2 = "".to_string();
        let mut buffer2_2 = "".to_string();
        let duration2 = FloatDuration::days(3.0) + FloatDuration::hours(12.0);

        write!(buffer2, "{}", duration2);
        write!(buffer2_2, "{}", duration2.decompose());
        assert_eq!(buffer2, "3.5 days");
        assert_eq!(buffer2_2, "3d 12:00:00.0");
    }
}

<commit_msg>Added `min_value` and `max_value` functions. Fixed some warnings.<commit_after>use std::time;
use std::fmt;
use std::ops;
use std::convert;
use std::f64;

use chrono;

use super::error;
use super::error::DurationError;

pub const SECS_PER_DAY: f64 = 60.0*60.0*24.0;
pub const SECS_PER_HOUR: f64 = 60.0*60.0;
pub const SECS_PER_MINUTE: f64 = 60.0;

pub trait TimePoint<Rhs=Self> {
    fn duration_between(&self, rhs: &Rhs) -> FloatDuration;
}

#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct FloatDuration {
    secs: f64,
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct DecomposedTime {
    pub days: u32,
    pub hours: u32,
    pub minutes: u32,
    pub seconds: u32,
    pub fractional_seconds: f64,
    pub sign: i8,
}

impl FloatDuration {
    pub fn new(secs: f64) -> FloatDuration {
        FloatDuration {secs}
    }

    pub fn days(days: f64) -> FloatDuration {
        FloatDuration {secs: days * (3600.0 * 24.0)}
    }
    pub fn hours(hours: f64) -> FloatDuration {
        FloatDuration {secs: hours * 3600.0}
    }
    pub fn minutes(mins: f64) -> FloatDuration {
        FloatDuration {secs: mins * 60.0}
    }
    pub fn seconds(secs: f64) -> FloatDuration {
        FloatDuration {secs}
    }
    pub fn milliseconds(millis: f64) -> FloatDuration {
        FloatDuration {secs: millis / 1000.0}
    }
    pub fn microseconds(micros: f64) -> FloatDuration {
        FloatDuration {secs: micros / 1.0e6}
    }
    pub fn nanoseconds(nanos: f64) -> FloatDuration {
        FloatDuration {secs: nanos / 1.0e9}
    }

    pub fn decompose(&self) -> DecomposedTime {
        let mut secs_left = self.secs;

        let days = (secs_left / SECS_PER_DAY).trunc();
        secs_left -= days*SECS_PER_DAY;
        let hours = (secs_left / SECS_PER_HOUR).trunc();
        secs_left -= hours*SECS_PER_HOUR;
        let minutes = (secs_left / SECS_PER_MINUTE).trunc();
        secs_left -= minutes*SECS_PER_MINUTE;
        let seconds = secs_left.trunc();
        let fract = secs_left.fract();

        DecomposedTime {
            days: days as u32,
            hours: hours as u32,
            minutes: minutes as u32,
            seconds: seconds as u32,
            fractional_seconds: fract,
            sign: self.secs.signum() as i8,
        }
    }

    pub fn as_days(&self) -> f64 {
        self.secs / SECS_PER_DAY
    }
    pub fn as_hours(&self) -> f64 {
        self.secs / SECS_PER_HOUR
    }
    pub fn as_minutes(&self) -> f64 {
        self.secs / SECS_PER_MINUTE
    }
    pub fn as_seconds(&self) -> f64 {
        self.secs
    }
    pub fn as_milliseconds(&self) -> f64 {
        self.secs * 1.0e3
    }
    pub fn as_microseconds(&self) -> f64 {
        self.secs * 1.0e6
    }
    pub fn as_nanoseconds(&self) -> f64 {
        self.secs * 1.0e9
    }

    pub fn zero() -> FloatDuration {
        FloatDuration {secs: 0.0}
    }
    pub fn is_zero(&self) -> bool {
        self.secs == 0.0
    }
    pub fn is_positive(&self) -> bool {
        self.secs.is_sign_positive()
    }
    pub fn is_negative(&self) -> bool {
        self.secs.is_sign_negative()
    }

    pub fn min_value() -> FloatDuration {
        FloatDuration { secs: f64::MIN }
    }
    pub fn max_value() -> FloatDuration {
        FloatDuration { secs: f64::MAX }
    }

    pub fn as_std(&self) -> error::Result<time::Duration> {
        if self.secs.is_sign_negative() {
            Err(DurationError::StdOutOfRange)
        } else {
            let seconds = self.secs.trunc();
            let nanos = self.secs.fract() * 1e9;

            Ok(time::Duration::new(seconds as u64, nanos as u32))
        }
    }

    pub fn from_std(duration: time::Duration) -> error::Result<FloatDuration> {
        Ok(FloatDuration::seconds(
            (duration.as_secs() as f64) + (duration.subsec_nanos() as f64)*1.0e-9))
    }

    pub fn from_decomposed(decomposed: &DecomposedTime) -> FloatDuration {
        let seconds = (decomposed.days as f64)*SECS_PER_DAY
            + (decomposed.hours as f64)*SECS_PER_HOUR
            + (decomposed.minutes as f64)*SECS_PER_MINUTE
            + (decomposed.seconds as f64)
            + decomposed.fractional_seconds;

        FloatDuration {
            secs: seconds
        }
    }
}

impl FloatDuration {
    pub fn as_chrono_duration(&self) -> error::Result<chrono::Duration> {
        let std_duration = self.as_std()?;
        chrono::Duration::from_std(std_duration).map_err(|e| convert::From::from(e))
    }

    pub fn from_chrono_duration(duration: &chrono::Duration)
            -> error::Result<FloatDuration>
    {
        let std_duration = duration.to_std()?;
        FloatDuration::from_std(std_duration)
    }
}

impl DecomposedTime {
    pub fn new() -> DecomposedTime {
        DecomposedTime { days: 0, hours: 0, minutes: 0, seconds: 0,
            fractional_seconds: 0.0, sign: 1 }
    }

    pub fn from_components(days: u32, hours: u32, minutes: u32,
               seconds: u32, fractional_seconds: f64) -> DecomposedTime
    {
        DecomposedTime {
            days, hours, minutes, seconds, fractional_seconds, sign: 1}
    }

    pub fn negate(mut self) -> DecomposedTime {
        self.sign *= -1;
        self
    }
}

impl fmt::Display for DecomposedTime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if self.days > 0 {
            write!(fmt, "{}d ", self.days as u64)?;
        }

        if self.sign.is_negative() {
            write!(fmt, "-")?;
        }
        write!(fmt, "{:02}:{:02}:{:02}.{}",
            self.hours,
            self.minutes,
            self.seconds,
            self.fractional_seconds)
    }
}

impl fmt::Display for FloatDuration {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if self.secs > SECS_PER_DAY {
            write!(fmt, "{} days", self.as_days())
        } else if self.secs > SECS_PER_HOUR {
            write!(fmt, "{} hours", self.as_hours())
        } else if self.secs > SECS_PER_MINUTE {
            write!(fmt, "{} minutes", self.as_minutes())
        } else if self.secs > 1.0 {
            write!(fmt, "{} seconds", self.as_seconds())
        } else if self.secs > 1.0e-3 {
            write!(fmt, "{} milliseconds", self.as_milliseconds())
        } else if self.secs > 1.0e-6 {
            write!(fmt, "{} microseconds", self.as_microseconds())
        } else {
            write!(fmt, "{} nanoseconds", self.as_nanoseconds())
        }
    }
}

impl ops::Neg for FloatDuration {
    type Output = FloatDuration;

    fn neg(self) -> FloatDuration {
        FloatDuration {secs: -self.secs}
    }
}

impl ops::Add<FloatDuration> for FloatDuration {
    type Output = FloatDuration;

    fn add(self, rhs: FloatDuration) -> FloatDuration {
        FloatDuration {secs: self.secs + rhs.secs}
    }
}
impl ops::Sub<FloatDuration> for FloatDuration {
    type Output = FloatDuration;

    fn sub(self, rhs: FloatDuration) -> FloatDuration {
        FloatDuration {secs: self.secs - rhs.secs}
    }
}

impl ops::Mul<f64> for FloatDuration {
    type Output = FloatDuration;

    fn mul(self, rhs: f64) -> FloatDuration {
        FloatDuration {secs: self.secs * rhs}
    }
}
impl ops::Div<f64> for FloatDuration {
    type Output = FloatDuration;

    fn div(self, rhs: f64) -> FloatDuration {
        FloatDuration {secs: self.secs / rhs}
    }
}

impl ops::AddAssign<FloatDuration> for FloatDuration {
    fn add_assign(&mut self, rhs: FloatDuration) {
        self.secs += rhs.secs;
    }
}
impl ops::SubAssign<FloatDuration> for FloatDuration {
    fn sub_assign(&mut self, rhs: FloatDuration) {
        self.secs -= rhs.secs;
    }
}

impl ops::MulAssign<f64> for FloatDuration {
    fn mul_assign(&mut self, rhs: f64) {
        self.secs *= rhs;
    }
}
impl ops::DivAssign<f64> for FloatDuration {
    fn div_assign(&mut self, rhs: f64) {
        self.secs /= rhs;
    }
}

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

    #[test]
    fn test_construct() {
        let duration1 = FloatDuration::hours(3.0);
        assert_eq!(duration1.as_hours(), 3.0);
        assert_eq!(duration1.as_minutes(), 180.0);
        assert_eq!(duration1.as_seconds(), 180.0*60.0);
        assert_eq!(duration1.as_days(), 3.0/24.0);
        assert_eq!(duration1.as_milliseconds(), 180.0*60.0*1000.0);

        let duration2 = FloatDuration::milliseconds(55.0);
        assert_eq!(duration2.as_seconds(), 0.055);
        assert_eq!(duration2.as_milliseconds(), 55.0);
        assert_eq!(duration2.as_microseconds(), 55000.0);
        assert_eq!(duration2.as_nanoseconds(), 55000000.0);
        assert!(!duration2.is_zero());

        let duration3 = FloatDuration::zero();
        assert!(duration3.is_zero());

        assert_eq!(FloatDuration::days(1.5), FloatDuration::hours(36.0));
        assert_eq!(FloatDuration::minutes(30.0), FloatDuration::hours(0.5));
        assert_eq!(FloatDuration::seconds(180.0), FloatDuration::minutes(3.0));
        assert_eq!(FloatDuration::seconds(3.5), FloatDuration::milliseconds(3500.0));
        assert_eq!(FloatDuration::microseconds(300.0), FloatDuration::milliseconds(0.30));
        assert_eq!(FloatDuration::nanoseconds(1000.0), FloatDuration::microseconds(1.0));
    }

    #[test]
    fn test_arithmetic() {
        let duration1 = FloatDuration::minutes(5.0) + FloatDuration::seconds(30.0);
        assert_eq!(duration1, FloatDuration::seconds(330.0));

        let duration2 = FloatDuration::hours(3.0) * 2.5;
        assert_eq!(duration2, FloatDuration::hours(7.5));

        let duration3 = FloatDuration::days(3.0) / 3.0 - FloatDuration::hours(2.0);
        assert_eq!(duration3, FloatDuration::hours(22.0));

        let duration4 = FloatDuration::zero() + FloatDuration::milliseconds(500.0)
            + FloatDuration::microseconds(500.0);
        assert_eq!(duration4, FloatDuration::microseconds(500500.0));

    }

    #[test]
    fn test_std_conversion() {
        let duration1 = FloatDuration::minutes(5.0);
        let std_duration1 = duration1.as_std().unwrap();
        assert!(duration1.is_positive());
        assert_eq!(std_duration1, time::Duration::new(300, 0));
        assert_eq!(FloatDuration::from_std(std_duration1).unwrap(), duration1);

        let duration2 = FloatDuration::hours(-2.0);
        assert!(duration2.is_negative());
        assert!(!duration2.as_std().is_ok());
        let std_duration2 = (-duration2).as_std().unwrap();
        assert_eq!(std_duration2, time::Duration::new(3600*2, 0));
        assert_eq!(FloatDuration::from_std(std_duration2).unwrap(), -duration2);
    }

    #[test]
    fn test_display() {
        use std::fmt::Write;

        let mut buffer1 = "".to_string();
        let mut buffer1_2 = "".to_string();
        let duration1 = FloatDuration::minutes(3.5);

        write!(buffer1, "{}", duration1).unwrap();
        write!(buffer1_2, "{}", duration1.decompose()).unwrap();
        assert_eq!(buffer1, "3.5 minutes");
        assert_eq!(buffer1_2, "00:03:30.0");

        let mut buffer2 = "".to_string();
        let mut buffer2_2 = "".to_string();
        let duration2 = FloatDuration::days(3.0) + FloatDuration::hours(12.0);

        write!(buffer2, "{}", duration2).unwrap();
        write!(buffer2_2, "{}", duration2.decompose()).unwrap();
        assert_eq!(buffer2, "3.5 days");
        assert_eq!(buffer2_2, "3d 12:00:00.0");
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# ears

__ears__ is a simple library for play Audio in Rust.

__ears__ is build on the top of OpenAL and libsndfile.

* Provide an acces to the OpenAL spatialization functionnality in a simple way.
* Accept a lot of audio format thanks to libsndfile.

# A simple example

```Rust
extern mod ears;
use ears::Sound;

fn main() -> {
	// Create a new Sound.
	let snd = Sound::new(~"path/to/my/sound.ogg").unwrap();

	// Play the Sound
	snd.play();

	// Wait until the end of the sound
	while snd.is_playing() {}
}
```

# Functionnality

__ears__ provide two way for play audio files.

* The Sound class, which represent light sounds who can share a buffer of samples with another Sound.
* The Music class, which is a bigger sound and who can't share sample buffer.

# Use ears

As said before, __ears__ require OpenAL and libsndfile, you need to install these two libraries in your system.

__ears__ compile against the last Rust compiler, so if it doesn't work on your computer you may need to update your compiler.

__ears__ work fully with `rustpkg`, so just install __ears__ in your project workspace like this :

```Shell
> rustpkg install github.com/JeremyLetang/ears
```

then import stuff from __ears__ in your project, you can import all the stuff :

```Rust
extern mod ears;

use ears::*;
```

or a specific :

```Rust
extern mod ears;

use ears::Music;
```

# Compile examples

Like __ears__ you can build the examples with `rustpkg`, just do :

```Shell
> rustpkg install examples/an_example
```
*/

#[feature(globs, macro_rules)];

#[link(name = "ears",
       vers = "0.0.1",
       package_id = "github.com/JeremyLetang/ears",
       author = "letang.jeremy@gmail.com",
       uuid = "D0271EC6-5F27-4C72-BBEA-1341DC665F34",
       url = "https://github.com/JeremyLetang/ears")];

#[desc = "Easy Api in Rust for Sounds"];
#[license = "MIT"];
#[crate_type = "lib"];

extern mod extra;

// Reexport public API
pub use music::Music;
pub use sound::Sound;
pub use states::{State, Initial, Playing, Paused, Stopped};
pub use sound_data::SoundData;
pub use audio_controller::AudioController;
pub use audio_tags::{AudioTags, Tags};

// Hidden internal bindings
#[doc(hidden)]
pub mod internal;
#[doc(hidden)]
mod openal;
#[doc(hidden)]
mod sndfile;

// The public ears API
pub mod init;
pub mod listener;
pub mod sound;
pub mod music;
pub mod sound_data;
pub mod states;
pub mod audio_controller;
pub mod audio_tags;
pub mod recorder;
<commit_msg>rustpkg test<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
# ears

__ears__ is a simple library for play Audio in Rust.

__ears__ is build on the top of OpenAL and libsndfile.

* Provide an acces to the OpenAL spatialization functionnality in a simple way.
* Accept a lot of audio format thanks to libsndfile.

# A simple example

```Rust
extern mod ears;
use ears::Sound;

fn main() -> {
	// Create a new Sound.
	let snd = Sound::new(~"path/to/my/sound.ogg").unwrap();

	// Play the Sound
	snd.play();

	// Wait until the end of the sound
	while snd.is_playing() {}
}
```

# Functionnality

__ears__ provide two way for play audio files.

* The Sound class, which represent light sounds who can share a buffer of samples with another Sound.
* The Music class, which is a bigger sound and who can't share sample buffer.

# Use ears

As said before, __ears__ require OpenAL and libsndfile, you need to install these two libraries in your system.

__ears__ compile against the last Rust compiler, so if it doesn't work on your computer you may need to update your compiler.

__ears__ work fully with `rustpkg`, so just install __ears__ in your project workspace like this :

```Shell
> rustpkg install github.com/JeremyLetang/ears
```

then import stuff from __ears__ in your project, you can import all the stuff :

```Rust
extern mod ears;

use ears::*;
```

or a specific :

```Rust
extern mod ears;

use ears::Music;
```

# Compile examples

Like __ears__ you can build the examples with `rustpkg`, just do :

```Shell
> rustpkg install examples/an_example
```
*/

#[feature(globs, macro_rules)];

#[link(name = "src/ears",
       vers = "0.0.1",
       package_id = "github.com/JeremyLetang/ears",
       author = "letang.jeremy@gmail.com",
       uuid = "D0271EC6-5F27-4C72-BBEA-1341DC665F34",
       url = "https://github.com/JeremyLetang/ears")];

#[desc = "Easy Api in Rust for Sounds"];
#[license = "MIT"];
#[crate_type = "lib"];

extern mod extra;

// Reexport public API
pub use music::Music;
pub use sound::Sound;
pub use states::{State, Initial, Playing, Paused, Stopped};
pub use sound_data::SoundData;
pub use audio_controller::AudioController;
pub use audio_tags::{AudioTags, Tags};

// Hidden internal bindings
#[doc(hidden)]
pub mod internal;
#[doc(hidden)]
mod openal;
#[doc(hidden)]
mod sndfile;

// The public ears API
pub mod init;
pub mod listener;
pub mod sound;
pub mod music;
pub mod sound_data;
pub mod states;
pub mod audio_controller;
pub mod audio_tags;
pub mod recorder;
<|endoftext|>