<commit_before>use std::any::TypeId;
use std::collections::HashMap;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::marker;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::EnumValueDescriptorProto;
use crate::descriptor::FileDescriptorProto;
use crate::enums::ProtobufEnum;
use crate::enums::ProtobufEnumOrUnknown;
use crate::reflect::find_message_or_enum::find_message_or_enum;
use crate::reflect::find_message_or_enum::MessageOrEnum;
use crate::reflect::ProtobufValue;

/// Description for enum variant.
///
/// Used in reflection.
#[derive(Clone)]
pub struct EnumValueDescriptor {
    proto: &'static EnumValueDescriptorProto,
    protobuf_value: &'static dyn ProtobufValue,
    get_descriptor: &'static dyn GetEnumDescriptor,
}

impl PartialEq for EnumValueDescriptor {
    fn eq(&self, other: &EnumValueDescriptor) -> bool {
        self.enum_descriptor() == other.enum_descriptor() && self.value() == other.value()
    }
}

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

fn _assert_send_sync() {
    fn _assert_send_sync<T: Send + Sync>() {}
    _assert_send_sync::<EnumValueDescriptor>();
}

impl fmt::Debug for EnumValueDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumValueDescriptor")
            .field("proto", self.proto)
            .field("value", &"...")
            .finish()
    }
}

impl Copy for EnumValueDescriptor {}

impl EnumValueDescriptor {
    /// Name of enum variant as specified in proto file
    pub fn name(&self) -> &'static str {
        self.proto.get_name()
    }

    /// `i32` value of the enum variant
    pub fn value(&self) -> i32 {
        self.proto.get_number()
    }

    /// Convert to generic `ProtobufValue`
    pub fn protobuf_value(&self) -> &'static dyn ProtobufValue {
        self.protobuf_value
    }

    /// Get descriptor of enum holding this value.
    pub fn enum_descriptor(&self) -> &EnumDescriptor {
        self.get_descriptor.descriptor()
    }

    /// Convert this value descriptor into proper enum object.
    ///
    /// See [`EnumDescriptor::cast`](crate::reflect::EnumDescriptor::cast) for more details.
    pub fn cast<E: 'static>(&self) -> Option<E> {
        self.enum_descriptor().cast(self.value())
    }
}

trait GetEnumDescriptor: Send + Sync + 'static {
    fn descriptor(&self) -> &EnumDescriptor;
    unsafe fn copy_to(&self, value: i32, dest: *mut ());
}

struct GetDescriptorImpl<E: ProtobufEnum>(marker::PhantomData<E>);

impl<E: ProtobufEnum> GetEnumDescriptor for GetDescriptorImpl<E> {
    fn descriptor(&self) -> &EnumDescriptor {
        E::enum_descriptor_static()
    }

    unsafe fn copy_to(&self, value: i32, dest: *mut ()) {
        let e = E::from_i32(value).expect("unknown value");
        (&e as *const E).copy_to(dest as *mut E, 1);
    }
}

/// Dynamic representation of enum type.
///
/// Can be used in reflective operations.
pub struct EnumDescriptor {
    full_name: String,
    proto: &'static EnumDescriptorProto,
    values: Vec<EnumValueDescriptor>,
    /// Type id of `<E>`
    type_id: TypeId,
    /// Type id of `<ProtobufEnumOrUnknown<E>>`
    enum_or_unknown_type_id: TypeId,

    #[cfg(not(rustc_nightly))]
    get_descriptor: &'static dyn GetEnumDescriptor,

    index_by_name: HashMap<String, usize>,
    index_by_number: HashMap<i32, usize>,
}

impl fmt::Debug for EnumDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumDescriptor")
            .field("full_name", &self.full_name)
            .field("..", &"..")
            .finish()
    }
}

/// Identity comparison: message descriptor are equal if their addresses are equal
impl PartialEq for EnumDescriptor {
    fn eq(&self, other: &EnumDescriptor) -> bool {
        self as *const EnumDescriptor == other as *const EnumDescriptor
    }
}

impl EnumDescriptor {
    /// Enum name as given in `.proto` file
    pub fn name(&self) -> &'static str {
        self.proto.get_name()
    }

    /// Fully qualified protobuf name of enum
    pub fn full_name(&self) -> &str {
        &self.full_name[..]
    }

    /// Get `EnumDescriptor` object for given enum type
    pub fn for_type<E: ProtobufEnum>() -> &'static EnumDescriptor {
        E::enum_descriptor_static()
    }

    fn compute_full_name(
        package: &str,
        path_to_package: &str,
        proto: &EnumDescriptorProto,
    ) -> String {
        let mut full_name = package.to_owned();
        if path_to_package.len() != 0 {
            if full_name.len() != 0 {
                full_name.push('.');
            }
            full_name.push_str(path_to_package);
        }
        if full_name.len() != 0 {
            full_name.push('.');
        }
        full_name.push_str(proto.get_name());
        full_name
    }

    /// Separate function to reduce generated code size bloat.
    fn make_indices(proto: &EnumDescriptorProto) -> (HashMap<String, usize>, HashMap<i32, usize>) {
        let mut index_by_name = HashMap::new();
        let mut index_by_number = HashMap::new();
        for (i, v) in proto.value.iter().enumerate() {
            index_by_number.insert(v.get_number(), i);
            index_by_name.insert(v.get_name().to_string(), i);
        }

        (index_by_name, index_by_number)
    }

    /// Construct `EnumDescriptor` given enum name and `FileDescriptorProto`.
    ///
    /// This function is called from generated code, and should rarely be called directly.
    ///
    /// This function is not a part of public API.
    #[doc(hidden)]
    pub fn new<E>(name_in_file: &'static str, file: &'static FileDescriptorProto) -> EnumDescriptor
    where
        E: ProtobufEnum,
    {
        let (path_to_package, proto) = match find_message_or_enum(file, name_in_file) {
            (path_to_package, MessageOrEnum::Enum(e)) => (path_to_package, e),
            (_, MessageOrEnum::Message(_)) => panic!("not an enum"),
        };

        let (index_by_name, index_by_number) = EnumDescriptor::make_indices(proto);

        let proto_values = &proto.value;
        let code_values = E::values();
        assert_eq!(proto_values.len(), code_values.len());

        let get_descriptor = &GetDescriptorImpl(marker::PhantomData::<E>);

        let values = proto_values
            .iter()
            .zip(code_values)
            .map(|(p, c)| EnumValueDescriptor {
                proto: p,
                protobuf_value: c,
                get_descriptor,
            })
            .collect();

        EnumDescriptor {
            full_name: EnumDescriptor::compute_full_name(
                file.get_package(),
                &path_to_package,
                &proto,
            ),
            proto,
            values,
            type_id: TypeId::of::<E>(),
            enum_or_unknown_type_id: TypeId::of::<ProtobufEnumOrUnknown<E>>(),
            #[cfg(not(rustc_nightly))]
            get_descriptor,
            index_by_name,
            index_by_number,
        }
    }

    /// This enum values
    pub fn values(&self) -> &[EnumValueDescriptor] {
        &self.values
    }

    /// Find enum variant by name
    pub fn value_by_name<'a>(&'a self, name: &str) -> Option<&'a EnumValueDescriptor> {
        let &index = self.index_by_name.get(name)?;
        Some(&self.values[index])
    }

    /// Find enum variant by number
    pub fn value_by_number(&self, number: i32) -> Option<&EnumValueDescriptor> {
        let &index = self.index_by_number.get(&number)?;
        Some(&self.values[index])
    }

    pub(crate) fn value_by_number_or_default(&self, number: i32) -> &EnumValueDescriptor {
        match self.value_by_number(number) {
            Some(v) => v,
            None => &self.values()[0],
        }
    }

    /// Check if this enum descriptor corresponds given enum type
    ///
    /// ```
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::descriptor::field_descriptor_proto::Label;
    /// # use protobuf::reflect::EnumDescriptor;
    ///
    /// let descriptor: &EnumDescriptor = Label::enum_descriptor_static();
    ///
    /// assert!(descriptor.is::<Label>())
    /// ```
    pub fn is<E: 'static>(&self) -> bool {
        TypeId::of::<E>() == self.type_id
    }

    /// Create enum object from given value.
    ///
    /// Type parameter `E` can be either [`ProtobufEnum`](crate::ProtobufEnum)
    /// or [`ProtobufEnumOrUnknown`](crate::ProtobufEnumOrUnknown).
    ///
    /// # Panics
    ///
    /// This operation panics of `E` is `ProtobufEnum` and `value` is unknown.
    pub fn cast<E: 'static>(&self, value: i32) -> Option<E> {
        if TypeId::of::<E>() == self.type_id {
            Some(self.cast_to_protobuf_enum(value))
        } else if TypeId::of::<E>() == self.enum_or_unknown_type_id {
            Some(self.cast_to_protobuf_enum_or_unknown(value))
        } else {
            None
        }
    }

    #[cfg(rustc_nightly)]
    fn cast_to_protobuf_enum<E: 'static>(&self, value: i32) -> E {
        <E as cast_impl::CastValueToProtobufEnum>::cast(value).unwrap()
    }

    #[cfg(not(rustc_nightly))]
    fn cast_to_protobuf_enum<E: 'static>(&self, value: i32) -> E {
        use std::mem;
        unsafe {
            let mut r = mem::uninitialized();
            self.get_descriptor
                .copy_to(value, &mut r as *mut E as *mut ());
            r
        }
    }

    #[cfg(rustc_nightly)]
    fn cast_to_protobuf_enum_or_unknown<E: 'static>(&self, value: i32) -> E {
        <E as cast_impl::CastValueToProtobufEnumOrUnknown>::cast(value).unwrap()
    }

    #[cfg(not(rustc_nightly))]
    fn cast_to_protobuf_enum_or_unknown<E: 'static>(&self, value: i32) -> E {
        use std::mem;
        use std::ptr;
        debug_assert_eq!(mem::size_of::<E>(), mem::size_of::<i32>());
        unsafe {
            // This works because `ProtobufEnumOrUnknown<E>` is `#[repr(transparent)]`
            let mut r = mem::uninitialized();
            ptr::copy(&value, &mut r as *mut E as *mut i32, 1);
            r
        }
    }
}

#[cfg(rustc_nightly)]
mod cast_impl {
    use super::*;

    pub(crate) trait CastValueToProtobufEnumOrUnknown: Sized {
        fn cast(value: i32) -> Option<Self>;
    }

    impl<T> CastValueToProtobufEnumOrUnknown for T {
        default fn cast(_value: i32) -> Option<T> {
            None
        }
    }

    impl<E: ProtobufEnum> CastValueToProtobufEnumOrUnknown for ProtobufEnumOrUnknown<E> {
        fn cast(value: i32) -> Option<ProtobufEnumOrUnknown<E>> {
            Some(ProtobufEnumOrUnknown::from_i32(value))
        }
    }

    pub(crate) trait CastValueToProtobufEnum: Sized {
        fn cast(value: i32) -> Option<Self>;
    }

    impl<T> CastValueToProtobufEnum for T {
        default fn cast(_value: i32) -> Option<T> {
            None
        }
    }

    impl<E: ProtobufEnum> CastValueToProtobufEnum for E {
        fn cast(value: i32) -> Option<E> {
            Some(E::from_i32(value).expect(&format!("unknown enum value: {}", value)))
        }
    }
}
<commit_msg>EnumDescriptor::is type parameter is now restricted to ProtobufEnum<commit_after>use std::any::TypeId;
use std::collections::HashMap;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::marker;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::EnumValueDescriptorProto;
use crate::descriptor::FileDescriptorProto;
use crate::enums::ProtobufEnum;
use crate::enums::ProtobufEnumOrUnknown;
use crate::reflect::find_message_or_enum::find_message_or_enum;
use crate::reflect::find_message_or_enum::MessageOrEnum;
use crate::reflect::ProtobufValue;

/// Description for enum variant.
///
/// Used in reflection.
#[derive(Clone)]
pub struct EnumValueDescriptor {
    proto: &'static EnumValueDescriptorProto,
    protobuf_value: &'static dyn ProtobufValue,
    get_descriptor: &'static dyn GetEnumDescriptor,
}

impl PartialEq for EnumValueDescriptor {
    fn eq(&self, other: &EnumValueDescriptor) -> bool {
        self.enum_descriptor() == other.enum_descriptor() && self.value() == other.value()
    }
}

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

fn _assert_send_sync() {
    fn _assert_send_sync<T: Send + Sync>() {}
    _assert_send_sync::<EnumValueDescriptor>();
}

impl fmt::Debug for EnumValueDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumValueDescriptor")
            .field("proto", self.proto)
            .field("value", &"...")
            .finish()
    }
}

impl Copy for EnumValueDescriptor {}

impl EnumValueDescriptor {
    /// Name of enum variant as specified in proto file
    pub fn name(&self) -> &'static str {
        self.proto.get_name()
    }

    /// `i32` value of the enum variant
    pub fn value(&self) -> i32 {
        self.proto.get_number()
    }

    /// Convert to generic `ProtobufValue`
    pub fn protobuf_value(&self) -> &'static dyn ProtobufValue {
        self.protobuf_value
    }

    /// Get descriptor of enum holding this value.
    pub fn enum_descriptor(&self) -> &EnumDescriptor {
        self.get_descriptor.descriptor()
    }

    /// Convert this value descriptor into proper enum object.
    ///
    /// See [`EnumDescriptor::cast`](crate::reflect::EnumDescriptor::cast) for more details.
    pub fn cast<E: 'static>(&self) -> Option<E> {
        self.enum_descriptor().cast(self.value())
    }
}

trait GetEnumDescriptor: Send + Sync + 'static {
    fn descriptor(&self) -> &EnumDescriptor;
    unsafe fn copy_to(&self, value: i32, dest: *mut ());
}

struct GetDescriptorImpl<E: ProtobufEnum>(marker::PhantomData<E>);

impl<E: ProtobufEnum> GetEnumDescriptor for GetDescriptorImpl<E> {
    fn descriptor(&self) -> &EnumDescriptor {
        E::enum_descriptor_static()
    }

    unsafe fn copy_to(&self, value: i32, dest: *mut ()) {
        let e = E::from_i32(value).expect("unknown value");
        (&e as *const E).copy_to(dest as *mut E, 1);
    }
}

/// Dynamic representation of enum type.
///
/// Can be used in reflective operations.
pub struct EnumDescriptor {
    full_name: String,
    proto: &'static EnumDescriptorProto,
    values: Vec<EnumValueDescriptor>,
    /// Type id of `<E>`
    type_id: TypeId,
    /// Type id of `<ProtobufEnumOrUnknown<E>>`
    enum_or_unknown_type_id: TypeId,

    #[cfg(not(rustc_nightly))]
    get_descriptor: &'static dyn GetEnumDescriptor,

    index_by_name: HashMap<String, usize>,
    index_by_number: HashMap<i32, usize>,
}

impl fmt::Debug for EnumDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumDescriptor")
            .field("full_name", &self.full_name)
            .field("..", &"..")
            .finish()
    }
}

/// Identity comparison: message descriptor are equal if their addresses are equal
impl PartialEq for EnumDescriptor {
    fn eq(&self, other: &EnumDescriptor) -> bool {
        self as *const EnumDescriptor == other as *const EnumDescriptor
    }
}

impl EnumDescriptor {
    /// Enum name as given in `.proto` file
    pub fn name(&self) -> &'static str {
        self.proto.get_name()
    }

    /// Fully qualified protobuf name of enum
    pub fn full_name(&self) -> &str {
        &self.full_name[..]
    }

    /// Get `EnumDescriptor` object for given enum type
    pub fn for_type<E: ProtobufEnum>() -> &'static EnumDescriptor {
        E::enum_descriptor_static()
    }

    fn compute_full_name(
        package: &str,
        path_to_package: &str,
        proto: &EnumDescriptorProto,
    ) -> String {
        let mut full_name = package.to_owned();
        if path_to_package.len() != 0 {
            if full_name.len() != 0 {
                full_name.push('.');
            }
            full_name.push_str(path_to_package);
        }
        if full_name.len() != 0 {
            full_name.push('.');
        }
        full_name.push_str(proto.get_name());
        full_name
    }

    /// Separate function to reduce generated code size bloat.
    fn make_indices(proto: &EnumDescriptorProto) -> (HashMap<String, usize>, HashMap<i32, usize>) {
        let mut index_by_name = HashMap::new();
        let mut index_by_number = HashMap::new();
        for (i, v) in proto.value.iter().enumerate() {
            index_by_number.insert(v.get_number(), i);
            index_by_name.insert(v.get_name().to_string(), i);
        }

        (index_by_name, index_by_number)
    }

    /// Construct `EnumDescriptor` given enum name and `FileDescriptorProto`.
    ///
    /// This function is called from generated code, and should rarely be called directly.
    ///
    /// This function is not a part of public API.
    #[doc(hidden)]
    pub fn new<E>(name_in_file: &'static str, file: &'static FileDescriptorProto) -> EnumDescriptor
    where
        E: ProtobufEnum,
    {
        let (path_to_package, proto) = match find_message_or_enum(file, name_in_file) {
            (path_to_package, MessageOrEnum::Enum(e)) => (path_to_package, e),
            (_, MessageOrEnum::Message(_)) => panic!("not an enum"),
        };

        let (index_by_name, index_by_number) = EnumDescriptor::make_indices(proto);

        let proto_values = &proto.value;
        let code_values = E::values();
        assert_eq!(proto_values.len(), code_values.len());

        let get_descriptor = &GetDescriptorImpl(marker::PhantomData::<E>);

        let values = proto_values
            .iter()
            .zip(code_values)
            .map(|(p, c)| EnumValueDescriptor {
                proto: p,
                protobuf_value: c,
                get_descriptor,
            })
            .collect();

        EnumDescriptor {
            full_name: EnumDescriptor::compute_full_name(
                file.get_package(),
                &path_to_package,
                &proto,
            ),
            proto,
            values,
            type_id: TypeId::of::<E>(),
            enum_or_unknown_type_id: TypeId::of::<ProtobufEnumOrUnknown<E>>(),
            #[cfg(not(rustc_nightly))]
            get_descriptor,
            index_by_name,
            index_by_number,
        }
    }

    /// This enum values
    pub fn values(&self) -> &[EnumValueDescriptor] {
        &self.values
    }

    /// Find enum variant by name
    pub fn value_by_name<'a>(&'a self, name: &str) -> Option<&'a EnumValueDescriptor> {
        let &index = self.index_by_name.get(name)?;
        Some(&self.values[index])
    }

    /// Find enum variant by number
    pub fn value_by_number(&self, number: i32) -> Option<&EnumValueDescriptor> {
        let &index = self.index_by_number.get(&number)?;
        Some(&self.values[index])
    }

    pub(crate) fn value_by_number_or_default(&self, number: i32) -> &EnumValueDescriptor {
        match self.value_by_number(number) {
            Some(v) => v,
            None => &self.values()[0],
        }
    }

    /// Check if this enum descriptor corresponds given enum type
    ///
    /// ```
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::descriptor::field_descriptor_proto::Label;
    /// # use protobuf::reflect::EnumDescriptor;
    ///
    /// let descriptor: &EnumDescriptor = Label::enum_descriptor_static();
    ///
    /// assert!(descriptor.is::<Label>())
    /// ```
    pub fn is<E: ProtobufEnum>(&self) -> bool {
        TypeId::of::<E>() == self.type_id
    }

    /// Create enum object from given value.
    ///
    /// Type parameter `E` can be either [`ProtobufEnum`](crate::ProtobufEnum)
    /// or [`ProtobufEnumOrUnknown`](crate::ProtobufEnumOrUnknown).
    ///
    /// # Panics
    ///
    /// This operation panics of `E` is `ProtobufEnum` and `value` is unknown.
    pub fn cast<E: 'static>(&self, value: i32) -> Option<E> {
        if TypeId::of::<E>() == self.type_id {
            Some(self.cast_to_protobuf_enum(value))
        } else if TypeId::of::<E>() == self.enum_or_unknown_type_id {
            Some(self.cast_to_protobuf_enum_or_unknown(value))
        } else {
            None
        }
    }

    #[cfg(rustc_nightly)]
    fn cast_to_protobuf_enum<E: 'static>(&self, value: i32) -> E {
        <E as cast_impl::CastValueToProtobufEnum>::cast(value).unwrap()
    }

    #[cfg(not(rustc_nightly))]
    fn cast_to_protobuf_enum<E: 'static>(&self, value: i32) -> E {
        use std::mem;
        unsafe {
            let mut r = mem::uninitialized();
            self.get_descriptor
                .copy_to(value, &mut r as *mut E as *mut ());
            r
        }
    }

    #[cfg(rustc_nightly)]
    fn cast_to_protobuf_enum_or_unknown<E: 'static>(&self, value: i32) -> E {
        <E as cast_impl::CastValueToProtobufEnumOrUnknown>::cast(value).unwrap()
    }

    #[cfg(not(rustc_nightly))]
    fn cast_to_protobuf_enum_or_unknown<E: 'static>(&self, value: i32) -> E {
        use std::mem;
        use std::ptr;
        debug_assert_eq!(mem::size_of::<E>(), mem::size_of::<i32>());
        unsafe {
            // This works because `ProtobufEnumOrUnknown<E>` is `#[repr(transparent)]`
            let mut r = mem::uninitialized();
            ptr::copy(&value, &mut r as *mut E as *mut i32, 1);
            r
        }
    }
}

#[cfg(rustc_nightly)]
mod cast_impl {
    use super::*;

    pub(crate) trait CastValueToProtobufEnumOrUnknown: Sized {
        fn cast(value: i32) -> Option<Self>;
    }

    impl<T> CastValueToProtobufEnumOrUnknown for T {
        default fn cast(_value: i32) -> Option<T> {
            None
        }
    }

    impl<E: ProtobufEnum> CastValueToProtobufEnumOrUnknown for ProtobufEnumOrUnknown<E> {
        fn cast(value: i32) -> Option<ProtobufEnumOrUnknown<E>> {
            Some(ProtobufEnumOrUnknown::from_i32(value))
        }
    }

    pub(crate) trait CastValueToProtobufEnum: Sized {
        fn cast(value: i32) -> Option<Self>;
    }

    impl<T> CastValueToProtobufEnum for T {
        default fn cast(_value: i32) -> Option<T> {
            None
        }
    }

    impl<E: ProtobufEnum> CastValueToProtobufEnum for E {
        fn cast(value: i32) -> Option<E> {
            Some(E::from_i32(value).expect(&format!("unknown enum value: {}", value)))
        }
    }
}
<|endoftext|>


<commit_before>use euclid::{rect, TypedPoint2D, TypedRect};
use num::{Float, One, Zero};
use rand::distributions::{Distribution, Standard, Uniform};
use rand::Rng;
use seeded_rng;
use std::error::Error;
use std::fmt;
use std::hash::Hash;
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
///
/// Turns an input value into a noise value.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate calx;
/// # fn main() {
/// use rand::distributions::Uniform;
/// use calx::Noise;
///
/// let depth = Uniform::new_inclusive(-1.0, 1.0);
/// let z: f32 = depth.noise(&(12, 34));
/// assert_eq!(z, -0.6524992);
/// let z: f32 = depth.noise(&(34, 12));
/// assert_eq!(z, -0.56852627);
/// # }
/// ```
pub trait Noise<T> {
    fn noise(&self, seed: &impl Hash) -> T;
}

impl<T: Distribution<U>, U> Noise<U> for T {
    fn noise(&self, seed: &impl Hash) -> U { self.sample(&mut seeded_rng(&seed)) }
}

/// A deciban unit log odds value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
///
/// # Examples
///
/// ```
/// use calx::Deciban;
/// assert_eq!(0.0, Deciban::new(0.5).0);
/// assert_eq!(10, Deciban::new(0.909091).0 as i32);
///
/// assert_eq!(0.5, Deciban(0.0).to_p());
/// assert_eq!(24, (Deciban(-5.0).to_p() * 100.0) as i32);
/// ```
#[derive(Copy, Clone, PartialEq, PartialOrd, Default, Debug)]
pub struct Deciban(pub f32);

impl Deciban {
    /// Build a deciban value from a probability in [0, 1).
    pub fn new(p: f32) -> Deciban {
        debug_assert!(p >= 0.0 && p < 1.0);
        Deciban(10.0 * (p / (1.0 - p)).log(10.0))
    }

    /// Convert a deciban value to the corresponding probability in [0, 1).
    pub fn to_p(self) -> f32 { 1.0 - 1.0 / (1.0 + 10.0.powf(self.0 / 10.0)) }
}

impl Distribution<Deciban> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ::Deciban {
        Deciban::new(rng.gen_range(0.0, 1.0))
    }
}

impl Add for Deciban {
    type Output = Deciban;
    fn add(self, rhs: Deciban) -> Deciban { Deciban(self.0 + rhs.0) }
}

impl AddAssign for Deciban {
    fn add_assign(&mut self, rhs: Deciban) { self.0 += rhs.0; }
}

impl Sub for Deciban {
    type Output = Deciban;
    fn sub(self, rhs: Deciban) -> Deciban { Deciban(self.0 - rhs.0) }
}

impl SubAssign for Deciban {
    fn sub_assign(&mut self, rhs: Deciban) { self.0 -= rhs.0; }
}

/// Interpolate linearly between two values.
pub fn lerp<T, U, V, W>(a: U, b: U, t: T) -> W
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
{
    a + (b - a) * t
}

/// Sequence of points for linearly interpolating between them.
pub struct LerpPath<T, U> {
    points: Vec<(T, U)>,
}

impl<T, U, V, W> LerpPath<T, U>
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
    T: PartialOrd + Sub<T, Output = T> + Div<T, Output = T> + Copy + Zero,
{
    pub fn new(begin: (T, U), end: (T, U)) -> LerpPath<T, U> {
        let mut result = LerpPath {
            points: vec![begin],
        };
        result.add(end);
        result
    }

    pub fn add(&mut self, point: (T, U)) {
        for i in 0..self.points.len() {
            if point.0 == self.points[i].0 {
                // Avoid zero width intervals or we'll get division by zero down the road, just
                // replace the point if the position is exactly the same.
                self.points[i] = point;
                return;
            }
            if point.0 < self.points[i].0 {
                self.points.insert(i, point);
                return;
            }
        }

        self.points.push(point);
    }

    pub fn sample(&self, t: T) -> W {
        if t < self.points[0].0 {
            return lerp(self.points[0].1, self.points[0].1, T::zero());
        }

        for i in 1..self.points.len() {
            if t < self.points[i].0 {
                let scaled = (t - self.points[i - 1].0) / (self.points[i].0 - self.points[i - 1].0);
                return lerp(self.points[i - 1].1, self.points[i].1, scaled);
            }
        }

        lerp(
            self.points[self.points.len() - 1].1,
            self.points[self.points.len() - 1].1,
            T::zero(),
        )
    }
}

/// Single-pass weighted sample for iterations.
pub trait WeightedChoice {
    type Item;

    /// Choose an item from the iteration with probability weighted by item weight.
    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32;
}

impl<T, I: IntoIterator<Item = T> + Sized> WeightedChoice for I {
    type Item = T;

    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32,
    {
        let dist = Uniform::new(0.0, 1.0);
        let (_, ret) = self
            .into_iter()
            .fold((0.0, None), |(weight_sum, prev_item), item| {
                let item_weight = weight_fn(&item);
                debug_assert!(item_weight >= 0.0);
                let p = item_weight / (weight_sum + item_weight);
                let next_item = if dist.sample(rng) < p {
                    Some(item)
                } else {
                    prev_item
                };
                (weight_sum + item_weight, next_item)
            });
        ret
    }
}

/// Insert a 0 bit between the low 16 bits of a number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn spread_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits = (bits ^ (bits << 8)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits << 4)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits << 2)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits << 1)) & 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits
}

/// Remove every odd bit and compact the even bits into the lower half of the number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn compact_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits = (bits ^ (bits >> 1)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits >> 2)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits >> 4)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits >> 8)) & 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits
}

/// Repeatedly run a random generator that may fail until it succeeds.
pub fn retry_gen<R: Rng + ?Sized, T, E>(
    n_tries: usize,
    rng: &mut R,
    gen: impl Fn(&mut R) -> Result<T, E>,
) -> Result<T, E> {
    let mut ret = gen(rng);
    for _ in 0..(n_tries - 1) {
        if ret.is_ok() {
            return ret;
        }
        ret = gen(rng);
    }

    ret
}

/// Build an axis-aligned rectangle that contains the given points.
///
/// It will add unit distance to the right and bottom edges to make sure the resulting `TypedRect`
/// will contain all the points. It would beneath
///
/// # Examples
///
/// ```
/// # extern crate euclid;
/// # extern crate calx;
/// # fn main() {
/// use euclid::point2;
///
/// let points: Vec<euclid::Point2D<i32>> = vec![point2(2, 3), point2(4, 5), point2(6, 7)];
/// let rect = calx::bounding_rect(&points);
/// assert!(rect.contains(&point2(2, 3)));
/// assert!(rect.contains(&point2(6, 7)));
/// assert!(!rect.contains(&point2(7, 7)));
/// assert!(!rect.contains(&point2(2, 2)));
/// # }
/// ```
pub fn bounding_rect<'a, I, T, U>(points: I) -> TypedRect<T, U>
where
    I: IntoIterator<Item = &'a TypedPoint2D<T, U>>,
    T: Zero + One + Add + Sub<Output = T> + Ord + Copy + 'a,
    U: 'a,
{
    let mut iter = points.into_iter();
    if let Some(first) = iter.next() {
        let (mut min_x, mut min_y) = (first.x, first.y);
        let (mut max_x, mut max_y) = (first.x, first.y);

        for p in iter {
            min_x = min_x.min(p.x);
            min_y = min_y.min(p.y);
            max_x = max_x.max(p.x);
            max_y = max_y.max(p.y);
        }

        // Make the rect contain the edge points.
        max_x = max_x + T::one();
        max_y = max_y + T::one();

        rect(min_x, min_y, max_x - min_x, max_y - min_y)
    } else {
        TypedRect::zero()
    }
}

/// Error type for when you don't care about the type and just want to use a string message.
#[derive(Debug)]
pub struct GenericError(pub String);

impl Error for GenericError {}

impl fmt::Display for GenericError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
}

/// Construct a `GenericError`.
#[macro_export]
macro_rules! err {
    ($($arg:tt)*) => ($crate::GenericError(format!($($arg)*)));
}

/// Return a `Result<_, Box<Error>>` error with `GenericError` message.
#[macro_export]
macro_rules! die {
    ($($arg:tt)*) => (return Err(Box::new(err!($($arg)*))););
}
<commit_msg>Pathing in inner macro call<commit_after>use euclid::{rect, TypedPoint2D, TypedRect};
use num::{Float, One, Zero};
use rand::distributions::{Distribution, Standard, Uniform};
use rand::Rng;
use seeded_rng;
use std::error::Error;
use std::fmt;
use std::hash::Hash;
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};

/// Clamp a value to range.
pub fn clamp<C: PartialOrd + Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn {
        mn
    } else if x > mx {
        mx
    } else {
        x
    }
}

/// Deterministic noise.
///
/// Turns an input value into a noise value.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate calx;
/// # fn main() {
/// use rand::distributions::Uniform;
/// use calx::Noise;
///
/// let depth = Uniform::new_inclusive(-1.0, 1.0);
/// let z: f32 = depth.noise(&(12, 34));
/// assert_eq!(z, -0.6524992);
/// let z: f32 = depth.noise(&(34, 12));
/// assert_eq!(z, -0.56852627);
/// # }
/// ```
pub trait Noise<T> {
    fn noise(&self, seed: &impl Hash) -> T;
}

impl<T: Distribution<U>, U> Noise<U> for T {
    fn noise(&self, seed: &impl Hash) -> U { self.sample(&mut seeded_rng(&seed)) }
}

/// A deciban unit log odds value.
///
/// Log odds correspond to the Bayesian probability for a hypothesis that
/// has decibans * 1/10 log_2(10) bits of evidence in favor of it. They're
/// a bit like rolling a d20 but better.
///
/// # Examples
///
/// ```
/// use calx::Deciban;
/// assert_eq!(0.0, Deciban::new(0.5).0);
/// assert_eq!(10, Deciban::new(0.909091).0 as i32);
///
/// assert_eq!(0.5, Deciban(0.0).to_p());
/// assert_eq!(24, (Deciban(-5.0).to_p() * 100.0) as i32);
/// ```
#[derive(Copy, Clone, PartialEq, PartialOrd, Default, Debug)]
pub struct Deciban(pub f32);

impl Deciban {
    /// Build a deciban value from a probability in [0, 1).
    pub fn new(p: f32) -> Deciban {
        debug_assert!(p >= 0.0 && p < 1.0);
        Deciban(10.0 * (p / (1.0 - p)).log(10.0))
    }

    /// Convert a deciban value to the corresponding probability in [0, 1).
    pub fn to_p(self) -> f32 { 1.0 - 1.0 / (1.0 + 10.0.powf(self.0 / 10.0)) }
}

impl Distribution<Deciban> for Standard {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ::Deciban {
        Deciban::new(rng.gen_range(0.0, 1.0))
    }
}

impl Add for Deciban {
    type Output = Deciban;
    fn add(self, rhs: Deciban) -> Deciban { Deciban(self.0 + rhs.0) }
}

impl AddAssign for Deciban {
    fn add_assign(&mut self, rhs: Deciban) { self.0 += rhs.0; }
}

impl Sub for Deciban {
    type Output = Deciban;
    fn sub(self, rhs: Deciban) -> Deciban { Deciban(self.0 - rhs.0) }
}

impl SubAssign for Deciban {
    fn sub_assign(&mut self, rhs: Deciban) { self.0 -= rhs.0; }
}

/// Interpolate linearly between two values.
pub fn lerp<T, U, V, W>(a: U, b: U, t: T) -> W
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
{
    a + (b - a) * t
}

/// Sequence of points for linearly interpolating between them.
pub struct LerpPath<T, U> {
    points: Vec<(T, U)>,
}

impl<T, U, V, W> LerpPath<T, U>
where
    U: Add<V, Output = W> + Sub<U, Output = V> + Copy,
    V: Mul<T, Output = V>,
    T: PartialOrd + Sub<T, Output = T> + Div<T, Output = T> + Copy + Zero,
{
    pub fn new(begin: (T, U), end: (T, U)) -> LerpPath<T, U> {
        let mut result = LerpPath {
            points: vec![begin],
        };
        result.add(end);
        result
    }

    pub fn add(&mut self, point: (T, U)) {
        for i in 0..self.points.len() {
            if point.0 == self.points[i].0 {
                // Avoid zero width intervals or we'll get division by zero down the road, just
                // replace the point if the position is exactly the same.
                self.points[i] = point;
                return;
            }
            if point.0 < self.points[i].0 {
                self.points.insert(i, point);
                return;
            }
        }

        self.points.push(point);
    }

    pub fn sample(&self, t: T) -> W {
        if t < self.points[0].0 {
            return lerp(self.points[0].1, self.points[0].1, T::zero());
        }

        for i in 1..self.points.len() {
            if t < self.points[i].0 {
                let scaled = (t - self.points[i - 1].0) / (self.points[i].0 - self.points[i - 1].0);
                return lerp(self.points[i - 1].1, self.points[i].1, scaled);
            }
        }

        lerp(
            self.points[self.points.len() - 1].1,
            self.points[self.points.len() - 1].1,
            T::zero(),
        )
    }
}

/// Single-pass weighted sample for iterations.
pub trait WeightedChoice {
    type Item;

    /// Choose an item from the iteration with probability weighted by item weight.
    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32;
}

impl<T, I: IntoIterator<Item = T> + Sized> WeightedChoice for I {
    type Item = T;

    fn weighted_choice<R: Rng + ?Sized, F>(self, rng: &mut R, weight_fn: F) -> Option<Self::Item>
    where
        F: Fn(&Self::Item) -> f32,
    {
        let dist = Uniform::new(0.0, 1.0);
        let (_, ret) = self
            .into_iter()
            .fold((0.0, None), |(weight_sum, prev_item), item| {
                let item_weight = weight_fn(&item);
                debug_assert!(item_weight >= 0.0);
                let p = item_weight / (weight_sum + item_weight);
                let next_item = if dist.sample(rng) < p {
                    Some(item)
                } else {
                    prev_item
                };
                (weight_sum + item_weight, next_item)
            });
        ret
    }
}

/// Insert a 0 bit between the low 16 bits of a number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn spread_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits = (bits ^ (bits << 8)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits << 4)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits << 2)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits << 1)) & 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits
}

/// Remove every odd bit and compact the even bits into the lower half of the number.
///
/// Useful for <https://en.wikipedia.org/wiki/Z-order_curve>
#[inline(always)]
pub fn compact_bits_by_2(mut bits: u32) -> u32 {
    // from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
    bits &= /* --------------- */ 0b0101_0101_0101_0101_0101_0101_0101_0101;
    bits = (bits ^ (bits >> 1)) & 0b0011_0011_0011_0011_0011_0011_0011_0011;
    bits = (bits ^ (bits >> 2)) & 0b0000_1111_0000_1111_0000_1111_0000_1111;
    bits = (bits ^ (bits >> 4)) & 0b0000_0000_1111_1111_0000_0000_1111_1111;
    bits = (bits ^ (bits >> 8)) & 0b0000_0000_0000_0000_1111_1111_1111_1111;
    bits
}

/// Repeatedly run a random generator that may fail until it succeeds.
pub fn retry_gen<R: Rng + ?Sized, T, E>(
    n_tries: usize,
    rng: &mut R,
    gen: impl Fn(&mut R) -> Result<T, E>,
) -> Result<T, E> {
    let mut ret = gen(rng);
    for _ in 0..(n_tries - 1) {
        if ret.is_ok() {
            return ret;
        }
        ret = gen(rng);
    }

    ret
}

/// Build an axis-aligned rectangle that contains the given points.
///
/// It will add unit distance to the right and bottom edges to make sure the resulting `TypedRect`
/// will contain all the points. It would beneath
///
/// # Examples
///
/// ```
/// # extern crate euclid;
/// # extern crate calx;
/// # fn main() {
/// use euclid::point2;
///
/// let points: Vec<euclid::Point2D<i32>> = vec![point2(2, 3), point2(4, 5), point2(6, 7)];
/// let rect = calx::bounding_rect(&points);
/// assert!(rect.contains(&point2(2, 3)));
/// assert!(rect.contains(&point2(6, 7)));
/// assert!(!rect.contains(&point2(7, 7)));
/// assert!(!rect.contains(&point2(2, 2)));
/// # }
/// ```
pub fn bounding_rect<'a, I, T, U>(points: I) -> TypedRect<T, U>
where
    I: IntoIterator<Item = &'a TypedPoint2D<T, U>>,
    T: Zero + One + Add + Sub<Output = T> + Ord + Copy + 'a,
    U: 'a,
{
    let mut iter = points.into_iter();
    if let Some(first) = iter.next() {
        let (mut min_x, mut min_y) = (first.x, first.y);
        let (mut max_x, mut max_y) = (first.x, first.y);

        for p in iter {
            min_x = min_x.min(p.x);
            min_y = min_y.min(p.y);
            max_x = max_x.max(p.x);
            max_y = max_y.max(p.y);
        }

        // Make the rect contain the edge points.
        max_x = max_x + T::one();
        max_y = max_y + T::one();

        rect(min_x, min_y, max_x - min_x, max_y - min_y)
    } else {
        TypedRect::zero()
    }
}

/// Error type for when you don't care about the type and just want to use a string message.
#[derive(Debug)]
pub struct GenericError(pub String);

impl Error for GenericError {}

impl fmt::Display for GenericError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
}

/// Construct a `GenericError`.
#[macro_export]
macro_rules! err {
    ($($arg:tt)*) => ($crate::GenericError(format!($($arg)*)));
}

/// Return a `Result<_, Box<Error>>` error with `GenericError` message.
#[macro_export]
macro_rules! die {
    ($($arg:tt)*) => (return Err(Box::new($crate::err!($($arg)*))););
}
<|endoftext|>


<commit_before>use types::*;

use nom::{be_i8, be_u8, be_i16, be_u16, be_i32, be_u32, be_i64, be_u64, float, double};

named!(pub parse_value<AMQPValue>,                 switch!(parse_type,
    AMQPType::Boolean        => map!(call!(parse_boolean),          |b| AMQPValue::Boolean(b))        |
    AMQPType::ShortShortInt  => map!(call!(parse_short_short_int),  |i| AMQPValue::ShortShortInt(i))  |
    AMQPType::ShortShortUInt => map!(call!(parse_short_short_uint), |u| AMQPValue::ShortShortUInt(u)) |
    AMQPType::ShortInt       => map!(call!(parse_short_int),        |i| AMQPValue::ShortInt(i))       |
    AMQPType::ShortUInt      => map!(call!(parse_short_uint),       |u| AMQPValue::ShortUInt(u))      |
    AMQPType::LongInt        => map!(call!(parse_long_int),         |i| AMQPValue::LongInt(i))        |
    AMQPType::LongUInt       => map!(call!(parse_long_uint),        |u| AMQPValue::LongUInt(u))       |
    AMQPType::LongLongInt    => map!(call!(parse_long_long_int),    |i| AMQPValue::LongLongInt(i))    |
    AMQPType::LongLongUInt   => map!(call!(parse_long_long_uint),   |u| AMQPValue::LongLongUInt(u))   |
    AMQPType::Float          => map!(call!(parse_float),            |f| AMQPValue::Float(f))          |
    AMQPType::Double         => map!(call!(parse_double),           |d| AMQPValue::Double(d))         |
    AMQPType::DecimalValue   => map!(call!(parse_decimal_value),    |d| AMQPValue::DecimalValue(d))   |
    AMQPType::ShortString    => map!(call!(parse_short_string),     |s| AMQPValue::ShortString(s))    |
    AMQPType::LongString     => map!(call!(parse_long_string),      |s| AMQPValue::LongString(s))     |
    AMQPType::FieldArray     => map!(call!(parse_field_array),      |a| AMQPValue::FieldArray(a))     |
    AMQPType::Timestamp      => map!(call!(parse_timestamp),        |t| AMQPValue::Timestamp(t))      |
//    AMQPType::FieldTable     => map!(call!(parse_field_table),      |t| AMQPValue::FieldTable(t))     |
    AMQPType::Void           => value!(AMQPValue::Void)
));

named!(pub parse_type<AMQPType>,                   map_opt!(be_u8, |t| AMQPType::from_id(t as char)));

named!(pub parse_boolean<Boolean>,                 map!(be_u8, |b| b != 0));
named!(pub parse_short_short_int<ShortShortInt>,   call!(be_i8));
named!(pub parse_short_short_uint<ShortShortUInt>, call!(be_u8));
named!(pub parse_short_int<ShortInt>,              call!(be_i16));
named!(pub parse_short_uint<ShortUInt>,            call!(be_u16));
named!(pub parse_long_int<LongInt>,                call!(be_i32));
named!(pub parse_long_uint<LongUInt>,              call!(be_u32));
named!(pub parse_long_long_int<LongLongInt>,       call!(be_i64));
named!(pub parse_long_long_uint<LongLongUInt>,     call!(be_u64));
named!(pub parse_float<Float>,                     call!(float));
named!(pub parse_double<Double>,                   call!(double));
named!(pub parse_decimal_value<DecimalValue>,      do_parse!(scale: parse_short_short_uint >> value: parse_long_uint >> (DecimalValue { scale: scale, value: value, })));
named!(pub parse_short_string<ShortString>,        do_parse!(length: parse_short_short_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_long_string<LongString>,          do_parse!(length: parse_long_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_field_array<FieldArray>,          do_parse!(length: parse_long_int >> array: count!(parse_value, length as usize) >> (array)));
named!(pub parse_timestamp<Timestamp>,             call!(parse_long_long_uint));
<commit_msg>types: parse field table<commit_after>use types::*;

use nom::{be_i8, be_u8, be_i16, be_u16, be_i32, be_u32, be_i64, be_u64, float, double};

named!(pub parse_value<AMQPValue>,                 switch!(parse_type,
    AMQPType::Boolean        => map!(call!(parse_boolean),          |b| AMQPValue::Boolean(b))        |
    AMQPType::ShortShortInt  => map!(call!(parse_short_short_int),  |i| AMQPValue::ShortShortInt(i))  |
    AMQPType::ShortShortUInt => map!(call!(parse_short_short_uint), |u| AMQPValue::ShortShortUInt(u)) |
    AMQPType::ShortInt       => map!(call!(parse_short_int),        |i| AMQPValue::ShortInt(i))       |
    AMQPType::ShortUInt      => map!(call!(parse_short_uint),       |u| AMQPValue::ShortUInt(u))      |
    AMQPType::LongInt        => map!(call!(parse_long_int),         |i| AMQPValue::LongInt(i))        |
    AMQPType::LongUInt       => map!(call!(parse_long_uint),        |u| AMQPValue::LongUInt(u))       |
    AMQPType::LongLongInt    => map!(call!(parse_long_long_int),    |i| AMQPValue::LongLongInt(i))    |
    AMQPType::LongLongUInt   => map!(call!(parse_long_long_uint),   |u| AMQPValue::LongLongUInt(u))   |
    AMQPType::Float          => map!(call!(parse_float),            |f| AMQPValue::Float(f))          |
    AMQPType::Double         => map!(call!(parse_double),           |d| AMQPValue::Double(d))         |
    AMQPType::DecimalValue   => map!(call!(parse_decimal_value),    |d| AMQPValue::DecimalValue(d))   |
    AMQPType::ShortString    => map!(call!(parse_short_string),     |s| AMQPValue::ShortString(s))    |
    AMQPType::LongString     => map!(call!(parse_long_string),      |s| AMQPValue::LongString(s))     |
    AMQPType::FieldArray     => map!(call!(parse_field_array),      |a| AMQPValue::FieldArray(a))     |
    AMQPType::Timestamp      => map!(call!(parse_timestamp),        |t| AMQPValue::Timestamp(t))      |
    AMQPType::FieldTable     => map!(call!(parse_field_table),      |t| AMQPValue::FieldTable(t))     |
    AMQPType::Void           => value!(AMQPValue::Void)
));

named!(pub parse_type<AMQPType>,                   map_opt!(be_u8, |t| AMQPType::from_id(t as char)));

named!(pub parse_boolean<Boolean>,                 map!(be_u8, |b| b != 0));
named!(pub parse_short_short_int<ShortShortInt>,   call!(be_i8));
named!(pub parse_short_short_uint<ShortShortUInt>, call!(be_u8));
named!(pub parse_short_int<ShortInt>,              call!(be_i16));
named!(pub parse_short_uint<ShortUInt>,            call!(be_u16));
named!(pub parse_long_int<LongInt>,                call!(be_i32));
named!(pub parse_long_uint<LongUInt>,              call!(be_u32));
named!(pub parse_long_long_int<LongLongInt>,       call!(be_i64));
named!(pub parse_long_long_uint<LongLongUInt>,     call!(be_u64));
named!(pub parse_float<Float>,                     call!(float));
named!(pub parse_double<Double>,                   call!(double));
named!(pub parse_decimal_value<DecimalValue>,      do_parse!(scale: parse_short_short_uint >> value: parse_long_uint >> (DecimalValue { scale: scale, value: value, })));
named!(pub parse_short_string<ShortString>,        do_parse!(length: parse_short_short_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_long_string<LongString>,          do_parse!(length: parse_long_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_field_array<FieldArray>,          do_parse!(length: parse_long_int >> array: count!(parse_value, length as usize) >> (array)));
named!(pub parse_timestamp<Timestamp>,             call!(parse_long_long_uint));
named!(pub parse_field_table<FieldTable>,          do_parse!(length: parse_long_uint >> table: flat_map!(take!(length as usize), fold_many0!(complete!(pair!(parse_short_string, parse_value)), FieldTable::new(), |mut acc: FieldTable, (key, value)| {
    acc.insert(key, value);
    acc
})) >> (table)));
<|endoftext|>


<commit_before>#![crate_name="CSVProvider"]
#![crate_type="dylib"]

// why doesn't "lib" work?

// rustc 0.11.0-pre (b47f2226a25654c5b781d27a91f2fa5274b3a347 2014-06-28 14:31:37 +0000)

#![feature(globs, macro_rules, quote, managed_boxes, plugin_registrar)]

#![allow(unused_imports)]
#![allow(unused_variable)]
#![allow(uppercase_variables)]
#![allow(unnecessary_parens)]

extern crate syntax;
extern crate rustc;

use syntax::ast::{
   Name,
   TokenTree,
   Expr,
   ExprLit,
   ExprVec,
   LitStr,
   Ident,
   DUMMY_NODE_ID,
   MutImmutable
};
use syntax::codemap::Span;
use syntax::ext::base::{
   SyntaxExtension,
   BasicMacroExpander,
   ExtCtxt,
   MacResult,
   MacPat,
   MacItem,
   DummyResult,
   MacExpr,
   NormalTT
};
use std::gc::Gc;
use syntax::ext::quote::{
   //expand_parse_call
};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{InternedString, COMMA, EOF};

use std::io;
use std::io::fs;
use std::os;
use std::str;
use std::io::Process;
use syntax::ast;
use syntax::ast::Name;

use syntax::util::small_vector::SmallVector;

use std::collections::HashMap;
use std::gc::{Gc, GC};

use rustc::plugin::Registry;

#[plugin_registrar]
pub fn macro_registrar(reg: &mut Registry) {
   reg.register_macro("ProvideCSV_labels", provide_csv_given_labels);
}

#[deriving(Clone)]
struct Entry {
   str: InternedString,
   expr: Gc<Expr>
}

// see https://github.com/sfackler/syntax-ext-talk/blob/gh-pages/simple-ext/lib.rs
fn parse_entries(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
   let mut parser = parse::new_parser_from_tts(
       cx.parse_sess(),
       cx.cfg(),
       tts.iter()
          .map(|x| (*x).clone())
          .collect()
   );

   let mut entries: Vec<Entry> = Vec::new();

   let mut error = false;
   while parser.token != EOF {
      let entry = parser.parse_expr();

      let entry_str = match entry.node {
         ExprLit(lit) => {
            match lit.node {
               LitStr(ref s, _) => s.clone(),
               _ => {
                  cx.span_err(entry.span, "expected string literal (1)");
                  error = true;
                  InternedString::new("")
               }
            }
         }
         _ => {
                cx.span_err(entry.span, "expected string literal (2)");
                error = true;
                InternedString::new("")
         }
      };

      entries.push(Entry { str: entry_str, expr: entry });

      if !parser.eat(&COMMA) && parser.token != EOF {
         cx.span_err(parser.span, "expected `,`");
         return None;
      }
    }

   if error {
      return None;
   }

   Some(entries)
}

pub struct MacItems {
   items: Vec<Gc<ast::Item>>
}
impl MacItems {
   pub fn new(items: Vec<Gc<ast::Item>>) -> Box<MacResult> {
      box MacItems { items: items } as Box<MacResult>
   }
}
impl MacResult for MacItems {
   fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
      Some(SmallVector::many(self.items.clone()))
   }
}

fn parse_csv_row(raw: &str, expected_columns: Option<uint>) -> str::StrSplits {
   let mut it = raw.split_str(",");

   // take a pulse
   let _whatever = it.map(|xx| {
      println!("iterating over row elements: {}", xx.to_string());
      return xx;
   });

   match expected_columns {
      Some(count) => {
         if (count == it.count()) {
            println!("parse_csv_row: matching length expected");
         } else {
            println!("parse_csv_row: wrong length!");
         }
      },
      None => (),
   }

   return it;
}

fn provide_csv_given_labels(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult> {
   let mut entries = match parse_entries(cx, tts) {
      Some(entries) => entries,
      None => return DummyResult::expr(sp),
   };

   let icx : &ExtCtxt = cx;  // an immutable borrow

   let raw_name   : Entry = entries.remove(0).expect("should be given a type name");
   let raw_path   : Entry = entries.remove(0).expect("should be given a CSV file path");
   let raw_labels : Entry = entries.remove(0).expect("should be given column labels");

   let name   : InternedString = raw_name.str;
   let path   : InternedString = raw_path.str;
   let labels : InternedString = raw_labels.str;

   println!("provide_csv_given_labels: name:   {}", name);
   println!("provide_csv_given_labels: path:   {}", path);
   println!("provide_csv_given_labels: labels: {}", labels);

   // PENDING
   // read the CSV and try to get the type of data in it
   // create a type with
   //  * this name,
   //  * these labeled columns,
   //  * discovered type of data
   //  * a constructor which reads the whole file

   fn interned_to_ident(xx: InternedString) -> Ident {
      let yy: String = format!("{}", xx);
      let zz: &str = yy.as_slice();
      return token::str_to_ident(zz);
   }

   fn interned_to_ident_with_suffix(xx: InternedString, suff: &str) -> Ident {
      let yy: String = format!("{}{}", xx, suff);
      let zz: &str = yy.as_slice();
      return token::str_to_ident(zz);
   }

   let MyCsv    = interned_to_ident(name.clone());
   let MyCsvRow = interned_to_ident_with_suffix(name, "Row");
   let col0     = interned_to_ident(labels.clone());

   println!("Parsing given labels...");

   let labels1 = format!("{}", labels);
   let labels_iter = parse_csv_row(labels1.as_slice(), None);

   println!("Defining items in the CSV provider...");

   // TODO: iterate through call columns
   let item0 = quote_item!(icx,
      pub struct $MyCsvRow {
         pub $col0: String,
      }
   );

   let item1: Option<Gc<syntax::ast::Item>> = quote_item!(icx,
      pub struct $MyCsv {
         pub data: Vec<$MyCsvRow>,
      }
   );

   let item2: Option<Gc<syntax::ast::Item>> = quote_item!(icx,
      impl $MyCsv {
         pub fn new() -> $MyCsv {
            println!("HMMMMMM.");
            return $MyCsv {
               data: (vec![
                  $MyCsvRow { $col0: "zero".to_string() },
                  $MyCsvRow { $col0:  "one".to_string() },
                  $MyCsvRow { $col0:  "two".to_string() },
               ]),
            };
         }
      }
   );

   let items = vec![item0.expect("Should be able to make struct MyCsvRow"),
                    item1.expect("Should be able to make struct MyCsv."),
                    item2.expect("Should be able to implement MyCsv.")];

   println!("OK");

   return MacItems::new(items);
}

<commit_msg>I prefer vectors...<commit_after>#![crate_name="CSVProvider"]
#![crate_type="dylib"]

// why doesn't "lib" work?

// rustc 0.11.0-pre (b47f2226a25654c5b781d27a91f2fa5274b3a347 2014-06-28 14:31:37 +0000)

#![feature(globs, macro_rules, quote, managed_boxes, plugin_registrar)]

#![allow(unused_imports)]
#![allow(unused_variable)]
#![allow(uppercase_variables)]
#![allow(unnecessary_parens)]

extern crate syntax;
extern crate rustc;

use syntax::ast::{
   Name,
   TokenTree,
   Expr,
   ExprLit,
   ExprVec,
   LitStr,
   Ident,
   DUMMY_NODE_ID,
   MutImmutable
};
use syntax::codemap::Span;
use syntax::ext::base::{
   SyntaxExtension,
   BasicMacroExpander,
   ExtCtxt,
   MacResult,
   MacPat,
   MacItem,
   DummyResult,
   MacExpr,
   NormalTT
};
use std::gc::Gc;
use syntax::ext::quote::{
   //expand_parse_call
};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{InternedString, COMMA, EOF};

use std::io;
use std::io::fs;
use std::os;
use std::str;
use std::io::Process;
use syntax::ast;
use syntax::ast::Name;

use syntax::util::small_vector::SmallVector;

use std::collections::HashMap;
use std::gc::{Gc, GC};

use rustc::plugin::Registry;

#[plugin_registrar]
pub fn macro_registrar(reg: &mut Registry) {
   reg.register_macro("ProvideCSV_labels", provide_csv_given_labels);
}

#[deriving(Clone)]
struct Entry {
   str: InternedString,
   expr: Gc<Expr>
}

// see https://github.com/sfackler/syntax-ext-talk/blob/gh-pages/simple-ext/lib.rs
fn parse_entries(cx: &mut ExtCtxt, tts: &[TokenTree]) -> Option<Vec<Entry>> {
   let mut parser = parse::new_parser_from_tts(
       cx.parse_sess(),
       cx.cfg(),
       tts.iter()
          .map(|x| (*x).clone())
          .collect()
   );

   let mut entries: Vec<Entry> = Vec::new();

   let mut error = false;
   while parser.token != EOF {
      let entry = parser.parse_expr();

      let entry_str = match entry.node {
         ExprLit(lit) => {
            match lit.node {
               LitStr(ref s, _) => s.clone(),
               _ => {
                  cx.span_err(entry.span, "expected string literal (1)");
                  error = true;
                  InternedString::new("")
               }
            }
         }
         _ => {
                cx.span_err(entry.span, "expected string literal (2)");
                error = true;
                InternedString::new("")
         }
      };

      entries.push(Entry { str: entry_str, expr: entry });

      if !parser.eat(&COMMA) && parser.token != EOF {
         cx.span_err(parser.span, "expected `,`");
         return None;
      }
    }

   if error {
      return None;
   }

   Some(entries)
}

pub struct MacItems {
   items: Vec<Gc<ast::Item>>
}
impl MacItems {
   pub fn new(items: Vec<Gc<ast::Item>>) -> Box<MacResult> {
      box MacItems { items: items } as Box<MacResult>
   }
}
impl MacResult for MacItems {
   fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
      Some(SmallVector::many(self.items.clone()))
   }
}

fn parse_csv_row(raw: &str, expected_columns: Option<uint>) -> Vec<&str> {
   let data: Vec<&str> = raw.split_str(",").collect();

   match expected_columns {
      Some(count) => {
         if (count == data.len()) {
            println!("parse_csv_row: matching length expected");
         } else {
            println!("parse_csv_row: wrong length!");
         }
      },
      None => (),
   }

   return data;
}

fn provide_csv_given_labels(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult> {
   let mut entries = match parse_entries(cx, tts) {
      Some(entries) => entries,
      None => return DummyResult::expr(sp),
   };

   let icx : &ExtCtxt = cx;  // an immutable borrow

   let raw_name   : Entry = entries.remove(0).expect("should be given a type name");
   let raw_path   : Entry = entries.remove(0).expect("should be given a CSV file path");
   let raw_labels : Entry = entries.remove(0).expect("should be given column labels");

   let name   : InternedString = raw_name.str;
   let path   : InternedString = raw_path.str;
   let labels : InternedString = raw_labels.str;

   println!("provide_csv_given_labels: name:   {}", name);
   println!("provide_csv_given_labels: path:   {}", path);
   println!("provide_csv_given_labels: labels: {}", labels);

   // PENDING
   // read the CSV and try to get the type of data in it
   // create a type with
   //  * this name,
   //  * these labeled columns,
   //  * discovered type of data
   //  * a constructor which reads the whole file

   fn interned_to_ident(xx: InternedString) -> Ident {
      let yy: String = format!("{}", xx);
      let zz: &str = yy.as_slice();
      return token::str_to_ident(zz);
   }

   fn interned_to_ident_with_suffix(xx: InternedString, suff: &str) -> Ident {
      let yy: String = format!("{}{}", xx, suff);
      let zz: &str = yy.as_slice();
      return token::str_to_ident(zz);
   }

   let MyCsv    = interned_to_ident(name.clone());
   let MyCsvRow = interned_to_ident_with_suffix(name, "Row");
   let col0     = interned_to_ident(labels.clone());

   println!("Parsing given labels...");

   let labels1 = format!("{}", labels);
   let labels_iter = parse_csv_row(labels1.as_slice(), None);

   println!("Defining items in the CSV provider...");

   // TODO: iterate through call columns
   let item0 = quote_item!(icx,
      pub struct $MyCsvRow {
         pub $col0: String,
      }
   );

   let item1: Option<Gc<syntax::ast::Item>> = quote_item!(icx,
      pub struct $MyCsv {
         pub data: Vec<$MyCsvRow>,
      }
   );

   let item2: Option<Gc<syntax::ast::Item>> = quote_item!(icx,
      impl $MyCsv {
         pub fn new() -> $MyCsv {
            println!("HMMMMMM.");
            return $MyCsv {
               data: (vec![
                  $MyCsvRow { $col0: "zero".to_string() },
                  $MyCsvRow { $col0:  "one".to_string() },
                  $MyCsvRow { $col0:  "two".to_string() },
               ]),
            };
         }
      }
   );

   let items = vec![item0.expect("Should be able to make struct MyCsvRow"),
                    item1.expect("Should be able to make struct MyCsv."),
                    item2.expect("Should be able to implement MyCsv.")];

   println!("OK");

   return MacItems::new(items);
}

<|endoftext|>


<commit_before>use std::convert::From;
use std::error::Error as StdError;
use std::fmt::{self, Display};
use std::ffi::NulError;

#[derive(Debug)]
#[cfg_attr(feature = "clippy", allow(enum_variant_names))]
/// The generic "things can fail in a myriad of ways" enum. This type is not
/// intended to be exhaustively matched, and new variants may be added in the
/// future without a major version bump.
pub enum Error {
    InvalidCString(NulError),
    DatabaseError(
        DatabaseErrorKind,
        Box<DatabaseErrorInformation + Send + Sync>,
    ),
    NotFound,
    QueryBuilderError(Box<StdError + Send + Sync>),
    DeserializationError(Box<StdError + Send + Sync>),
    SerializationError(Box<StdError + Send + Sync>),
    /// You can return this variant inside of a transaction when you want to
    /// roll it back, but have no actual error to return. Diesel will never
    /// return this variant unless you gave it to us, and it can be safely
    /// ignored in error handling.
    RollbackTransaction,
    #[doc(hidden)] __Nonexhaustive,
}

#[derive(Debug, Clone, Copy)]
/// The kind of database error that occurred.
///
/// This is not meant to exhaustively cover all possible errors, but is used to
/// identify errors which are commonly recovered from programatically. This enum
/// is not intended to be exhaustively matched, and new variants may be added in
/// the future without a major version bump.
pub enum DatabaseErrorKind {
    /// A unique constraint was violated.
    UniqueViolation,
    /// A foreign key constraint was violated.
    ForeignKeyViolation,
    /// The query could not be sent to the database due to a protocol violation.
    ///
    /// An example of a case where this would occur is if you attempted to send
    /// a query with more than 65000 bind parameters using PostgreSQL.
    UnableToSendCommand,
    #[doc(hidden)] __Unknown, // Match against _ instead, more variants may be added in the future
}

/// Information about an error that was returned by the database.
pub trait DatabaseErrorInformation {
    /// The primary human-readable error message. Typically one line.
    fn message(&self) -> &str;

    /// An optional secondary error message providing more details about the
    /// problem, if it was provided by the database. Might span multiple lines.
    fn details(&self) -> Option<&str>;

    /// An optional suggestion of what to do about the problem, if one was
    /// provided by the database.
    fn hint(&self) -> Option<&str>;

    /// The name of the table the error was associated with, if the error was
    /// associated with a specific table and the backend supports retrieving
    /// that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn table_name(&self) -> Option<&str>;

    /// The name of the column the error was associated with, if the error was
    /// associated with a specific column and the backend supports retrieving
    /// that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn column_name(&self) -> Option<&str>;

    /// The constraint that was violated if this error is a constraint violation
    /// and the backend supports retrieving that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn constraint_name(&self) -> Option<&str>;
}

impl fmt::Debug for DatabaseErrorInformation + Send + Sync {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.message(), f)
    }
}

impl DatabaseErrorInformation for String {
    fn message(&self) -> &str {
        self
    }

    fn details(&self) -> Option<&str> {
        None
    }
    fn hint(&self) -> Option<&str> {
        None
    }
    fn table_name(&self) -> Option<&str> {
        None
    }
    fn column_name(&self) -> Option<&str> {
        None
    }
    fn constraint_name(&self) -> Option<&str> {
        None
    }
}

/// Errors which can occur during [`Connection::establish`]
///
/// [`Connection::establish`]: ../connection/trait.Connection.html?search=#tymethod.establish
#[derive(Debug)]
pub enum ConnectionError {
    /// The connection URL contained a `NUL` byte.
    InvalidCString(NulError),
    /// The database returned an error.
    BadConnection(String),
    /// The connection URL could not be parsed.
    InvalidConnectionUrl(String),
    /// Diesel could not configure the database connection.
    ///
    /// Diesel may try to automatically set session specific configuration
    /// values, such as UTF8 encoding, or enabling the `||` operator on MySQL.
    /// This variant is returned if an error occurred executing the query to set
    /// those options. Diesel will never affect global configuration.
    CouldntSetupConfiguration(Error),
    #[doc(hidden)] __Nonexhaustive, // Match against _ instead, more variants may be added in the future
}

/// A specialized result type for queries.
///
/// This type is exported by `diesel::prelude`, and is generally used by any
/// code which is interacting with Diesel. This type exists to avoid writing out
/// `diesel::result::Error`, and is otherwise a direct mapping to `Result`.
pub type QueryResult<T> = Result<T, Error>;

/// A specialized result type for establishing connections.
///
/// This type exists to avoid writing out `diesel::result::ConnectionError`, and
/// is otherwise a direct mapping to `Result`.
pub type ConnectionResult<T> = Result<T, ConnectionError>;

/// See the [method documentation](#tymethod.optional).
pub trait OptionalExtension<T> {
    /// Converts a `QueryResult<T>` into a `QueryResult<Option<T>>`.
    ///
    /// By default, Diesel treats 0 rows being returned from a query that is expected to return 1
    /// row as an error (e.g. the return value of [`get_result`] or [`first`]). This method will
    /// handle that error, and give you back an `Option<T>` instead.
    ///
    /// [`get_result`]: ../prelude/trait.LoadDsl.html#method.get_result
    /// [`first`]: ../prelude/trait.FirstDsl.html#method.first
    ///
    /// # Example
    ///
    /// ```rust
    /// use diesel::result::{QueryResult, Error};
    /// use diesel::OptionalExtension;
    ///
    /// let result: QueryResult<i32> = Ok(1);
    /// assert_eq!(Ok(Some(1)), result.optional());
    ///
    /// let result: QueryResult<i32> = Err(Error::NotFound);
    /// assert_eq!(Ok(None), result.optional());
    /// ```
    fn optional(self) -> Result<Option<T>, Error>;
}

impl<T> OptionalExtension<T> for QueryResult<T> {
    fn optional(self) -> Result<Option<T>, Error> {
        match self {
            Ok(value) => Ok(Some(value)),
            Err(Error::NotFound) => Ok(None),
            Err(e) => Err(e),
        }
    }
}

impl From<NulError> for ConnectionError {
    fn from(e: NulError) -> Self {
        ConnectionError::InvalidCString(e)
    }
}

impl From<NulError> for Error {
    fn from(e: NulError) -> Self {
        Error::InvalidCString(e)
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::InvalidCString(ref nul_err) => nul_err.fmt(f),
            Error::DatabaseError(_, ref e) => write!(f, "{}", e.message()),
            Error::NotFound => f.write_str("NotFound"),
            Error::QueryBuilderError(ref e) => e.fmt(f),
            Error::DeserializationError(ref e) => e.fmt(f),
            Error::SerializationError(ref e) => e.fmt(f),
            Error::RollbackTransaction => write!(f, "{}", self.description()),
            Error::__Nonexhaustive => unreachable!(),
        }
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::InvalidCString(ref nul_err) => nul_err.description(),
            Error::DatabaseError(_, ref e) => e.message(),
            Error::NotFound => "Record not found",
            Error::QueryBuilderError(ref e) => e.description(),
            Error::DeserializationError(ref e) => e.description(),
            Error::SerializationError(ref e) => e.description(),
            Error::RollbackTransaction => "The current transaction was aborted",
            Error::__Nonexhaustive => unreachable!(),
        }
    }
}

impl Display for ConnectionError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ConnectionError::InvalidCString(ref nul_err) => nul_err.fmt(f),
            ConnectionError::BadConnection(ref s) => write!(f, "{}", s),
            ConnectionError::InvalidConnectionUrl(ref s) => write!(f, "{}", s),
            ConnectionError::CouldntSetupConfiguration(ref e) => e.fmt(f),
            ConnectionError::__Nonexhaustive => unreachable!(),
        }
    }
}

impl StdError for ConnectionError {
    fn description(&self) -> &str {
        match *self {
            ConnectionError::InvalidCString(ref nul_err) => nul_err.description(),
            ConnectionError::BadConnection(ref s) => s,
            ConnectionError::InvalidConnectionUrl(ref s) => s,
            ConnectionError::CouldntSetupConfiguration(ref e) => e.description(),
            ConnectionError::__Nonexhaustive => unreachable!(),
        }
    }
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        match (self, other) {
            (&Error::InvalidCString(ref a), &Error::InvalidCString(ref b)) => a == b,
            (&Error::DatabaseError(_, ref a), &Error::DatabaseError(_, ref b)) => {
                a.message() == b.message()
            }
            (&Error::NotFound, &Error::NotFound) => true,
            _ => false,
        }
    }
}

#[cfg(test)]
#[allow(warnings)]
fn error_impls_send() {
    let err: Error = unimplemented!();
    let x: &Send = &err;
}

pub(crate) fn first_or_not_found<T>(records: QueryResult<Vec<T>>) -> QueryResult<T> {
    records?.into_iter().next().ok_or(Error::NotFound)
}
<commit_msg>Document the `result` module [ci skip]<commit_after>//! Errors, type aliases, and functions related to working with `Result`.

use std::convert::From;
use std::error::Error as StdError;
use std::fmt::{self, Display};
use std::ffi::NulError;

#[derive(Debug)]
#[cfg_attr(feature = "clippy", allow(enum_variant_names))]
/// The generic "things can fail in a myriad of ways" enum. This type is not
/// intended to be exhaustively matched, and new variants may be added in the
/// future without a major version bump.
pub enum Error {
    InvalidCString(NulError),
    DatabaseError(
        DatabaseErrorKind,
        Box<DatabaseErrorInformation + Send + Sync>,
    ),
    NotFound,
    QueryBuilderError(Box<StdError + Send + Sync>),
    DeserializationError(Box<StdError + Send + Sync>),
    SerializationError(Box<StdError + Send + Sync>),
    /// You can return this variant inside of a transaction when you want to
    /// roll it back, but have no actual error to return. Diesel will never
    /// return this variant unless you gave it to us, and it can be safely
    /// ignored in error handling.
    RollbackTransaction,
    #[doc(hidden)] __Nonexhaustive,
}

#[derive(Debug, Clone, Copy)]
/// The kind of database error that occurred.
///
/// This is not meant to exhaustively cover all possible errors, but is used to
/// identify errors which are commonly recovered from programatically. This enum
/// is not intended to be exhaustively matched, and new variants may be added in
/// the future without a major version bump.
pub enum DatabaseErrorKind {
    /// A unique constraint was violated.
    UniqueViolation,
    /// A foreign key constraint was violated.
    ForeignKeyViolation,
    /// The query could not be sent to the database due to a protocol violation.
    ///
    /// An example of a case where this would occur is if you attempted to send
    /// a query with more than 65000 bind parameters using PostgreSQL.
    UnableToSendCommand,
    #[doc(hidden)] __Unknown, // Match against _ instead, more variants may be added in the future
}

/// Information about an error that was returned by the database.
pub trait DatabaseErrorInformation {
    /// The primary human-readable error message. Typically one line.
    fn message(&self) -> &str;

    /// An optional secondary error message providing more details about the
    /// problem, if it was provided by the database. Might span multiple lines.
    fn details(&self) -> Option<&str>;

    /// An optional suggestion of what to do about the problem, if one was
    /// provided by the database.
    fn hint(&self) -> Option<&str>;

    /// The name of the table the error was associated with, if the error was
    /// associated with a specific table and the backend supports retrieving
    /// that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn table_name(&self) -> Option<&str>;

    /// The name of the column the error was associated with, if the error was
    /// associated with a specific column and the backend supports retrieving
    /// that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn column_name(&self) -> Option<&str>;

    /// The constraint that was violated if this error is a constraint violation
    /// and the backend supports retrieving that information.
    ///
    /// Currently this method will return `None` for all backends other than
    /// PostgreSQL.
    fn constraint_name(&self) -> Option<&str>;
}

impl fmt::Debug for DatabaseErrorInformation + Send + Sync {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.message(), f)
    }
}

impl DatabaseErrorInformation for String {
    fn message(&self) -> &str {
        self
    }

    fn details(&self) -> Option<&str> {
        None
    }
    fn hint(&self) -> Option<&str> {
        None
    }
    fn table_name(&self) -> Option<&str> {
        None
    }
    fn column_name(&self) -> Option<&str> {
        None
    }
    fn constraint_name(&self) -> Option<&str> {
        None
    }
}

/// Errors which can occur during [`Connection::establish`]
///
/// [`Connection::establish`]: ../connection/trait.Connection.html?search=#tymethod.establish
#[derive(Debug)]
pub enum ConnectionError {
    /// The connection URL contained a `NUL` byte.
    InvalidCString(NulError),
    /// The database returned an error.
    BadConnection(String),
    /// The connection URL could not be parsed.
    InvalidConnectionUrl(String),
    /// Diesel could not configure the database connection.
    ///
    /// Diesel may try to automatically set session specific configuration
    /// values, such as UTF8 encoding, or enabling the `||` operator on MySQL.
    /// This variant is returned if an error occurred executing the query to set
    /// those options. Diesel will never affect global configuration.
    CouldntSetupConfiguration(Error),
    #[doc(hidden)] __Nonexhaustive, // Match against _ instead, more variants may be added in the future
}

/// A specialized result type for queries.
///
/// This type is exported by `diesel::prelude`, and is generally used by any
/// code which is interacting with Diesel. This type exists to avoid writing out
/// `diesel::result::Error`, and is otherwise a direct mapping to `Result`.
pub type QueryResult<T> = Result<T, Error>;

/// A specialized result type for establishing connections.
///
/// This type exists to avoid writing out `diesel::result::ConnectionError`, and
/// is otherwise a direct mapping to `Result`.
pub type ConnectionResult<T> = Result<T, ConnectionError>;

/// See the [method documentation](#tymethod.optional).
pub trait OptionalExtension<T> {
    /// Converts a `QueryResult<T>` into a `QueryResult<Option<T>>`.
    ///
    /// By default, Diesel treats 0 rows being returned from a query that is expected to return 1
    /// row as an error (e.g. the return value of [`get_result`] or [`first`]). This method will
    /// handle that error, and give you back an `Option<T>` instead.
    ///
    /// [`get_result`]: ../prelude/trait.LoadDsl.html#method.get_result
    /// [`first`]: ../prelude/trait.FirstDsl.html#method.first
    ///
    /// # Example
    ///
    /// ```rust
    /// use diesel::result::{QueryResult, Error};
    /// use diesel::OptionalExtension;
    ///
    /// let result: QueryResult<i32> = Ok(1);
    /// assert_eq!(Ok(Some(1)), result.optional());
    ///
    /// let result: QueryResult<i32> = Err(Error::NotFound);
    /// assert_eq!(Ok(None), result.optional());
    /// ```
    fn optional(self) -> Result<Option<T>, Error>;
}

impl<T> OptionalExtension<T> for QueryResult<T> {
    fn optional(self) -> Result<Option<T>, Error> {
        match self {
            Ok(value) => Ok(Some(value)),
            Err(Error::NotFound) => Ok(None),
            Err(e) => Err(e),
        }
    }
}

impl From<NulError> for ConnectionError {
    fn from(e: NulError) -> Self {
        ConnectionError::InvalidCString(e)
    }
}

impl From<NulError> for Error {
    fn from(e: NulError) -> Self {
        Error::InvalidCString(e)
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::InvalidCString(ref nul_err) => nul_err.fmt(f),
            Error::DatabaseError(_, ref e) => write!(f, "{}", e.message()),
            Error::NotFound => f.write_str("NotFound"),
            Error::QueryBuilderError(ref e) => e.fmt(f),
            Error::DeserializationError(ref e) => e.fmt(f),
            Error::SerializationError(ref e) => e.fmt(f),
            Error::RollbackTransaction => write!(f, "{}", self.description()),
            Error::__Nonexhaustive => unreachable!(),
        }
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::InvalidCString(ref nul_err) => nul_err.description(),
            Error::DatabaseError(_, ref e) => e.message(),
            Error::NotFound => "Record not found",
            Error::QueryBuilderError(ref e) => e.description(),
            Error::DeserializationError(ref e) => e.description(),
            Error::SerializationError(ref e) => e.description(),
            Error::RollbackTransaction => "The current transaction was aborted",
            Error::__Nonexhaustive => unreachable!(),
        }
    }
}

impl Display for ConnectionError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ConnectionError::InvalidCString(ref nul_err) => nul_err.fmt(f),
            ConnectionError::BadConnection(ref s) => write!(f, "{}", s),
            ConnectionError::InvalidConnectionUrl(ref s) => write!(f, "{}", s),
            ConnectionError::CouldntSetupConfiguration(ref e) => e.fmt(f),
            ConnectionError::__Nonexhaustive => unreachable!(),
        }
    }
}

impl StdError for ConnectionError {
    fn description(&self) -> &str {
        match *self {
            ConnectionError::InvalidCString(ref nul_err) => nul_err.description(),
            ConnectionError::BadConnection(ref s) => s,
            ConnectionError::InvalidConnectionUrl(ref s) => s,
            ConnectionError::CouldntSetupConfiguration(ref e) => e.description(),
            ConnectionError::__Nonexhaustive => unreachable!(),
        }
    }
}

impl PartialEq for Error {
    fn eq(&self, other: &Error) -> bool {
        match (self, other) {
            (&Error::InvalidCString(ref a), &Error::InvalidCString(ref b)) => a == b,
            (&Error::DatabaseError(_, ref a), &Error::DatabaseError(_, ref b)) => {
                a.message() == b.message()
            }
            (&Error::NotFound, &Error::NotFound) => true,
            _ => false,
        }
    }
}

#[cfg(test)]
#[allow(warnings)]
fn error_impls_send() {
    let err: Error = unimplemented!();
    let x: &Send = &err;
}

pub(crate) fn first_or_not_found<T>(records: QueryResult<Vec<T>>) -> QueryResult<T> {
    records?.into_iter().next().ok_or(Error::NotFound)
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

#[no_mangle]
pub extern "C" fn acos(n: f64) -> f64 {
	libm::acos(n)
}

#[no_mangle]
pub extern "C" fn acosf(n: f32) -> f32 {
	libm::acosf(n)
}

#[no_mangle]
pub extern "C" fn acosh(x: f64) -> f64 {
	libm::acosh(x)
}

#[no_mangle]
pub extern "C" fn acoshf(x: f32) -> f32 {
	libm::acoshf(x)
}

#[no_mangle]
pub extern "C" fn asin(n: f64) -> f64 {
	libm::asin(n)
}

#[no_mangle]
pub extern "C" fn asinf(n: f32) -> f32 {
	libm::asinf(n)
}

#[no_mangle]
pub extern "C" fn asinh(x: f64) -> f64 {
	libm::asinh(x)
}

#[no_mangle]
pub extern "C" fn asinhf(x: f32) -> f32 {
	libm::asinhf(x)
}

#[no_mangle]
pub extern "C" fn atan(n: f64) -> f64 {
	libm::atan(n)
}

#[no_mangle]
pub extern "C" fn atan2(a: f64, b: f64) -> f64 {
	libm::atan2(a, b)
}

#[no_mangle]
pub extern "C" fn atan2f(a: f32, b: f32) -> f32 {
	libm::atan2f(a, b)
}

#[no_mangle]
pub extern "C" fn atanf(n: f32) -> f32 {
	libm::atanf(n)
}

#[no_mangle]
pub extern "C" fn cbrt(n: f64) -> f64 {
	libm::cbrt(n)
}

#[no_mangle]
pub extern "C" fn cbrtf(n: f32) -> f32 {
	libm::cbrtf(n)
}

#[no_mangle]
pub extern "C" fn ceil(x: f64) -> f64 {
	libm::ceil(x)
}

#[no_mangle]
pub extern "C" fn ceilf(x: f32) -> f32 {
	libm::ceilf(x)
}

#[no_mangle]
pub extern "C" fn cos(x: f64) -> f64 {
	libm::cos(x)
}

#[no_mangle]
pub extern "C" fn cosf(x: f32) -> f32 {
	libm::cosf(x)
}

#[no_mangle]
pub extern "C" fn cosh(x: f64) -> f64 {
	libm::cosh(x)
}

#[no_mangle]
pub extern "C" fn coshf(x: f32) -> f32 {
	libm::coshf(x)
}

#[no_mangle]
pub extern "C" fn exp(x: f64) -> f64 {
	libm::exp(x)
}

#[no_mangle]
pub extern "C" fn expf(x: f32) -> f32 {
	libm::expf(x)
}

#[no_mangle]
pub extern "C" fn expm1(n: f64) -> f64 {
	libm::expm1(n)
}

#[no_mangle]
pub extern "C" fn expm1f(n: f32) -> f32 {
	libm::expm1f(n)
}

#[no_mangle]
pub extern "C" fn fdim(a: f64, b: f64) -> f64 {
	libm::fdim(a, b)
}

#[no_mangle]
pub extern "C" fn fdimf(a: f32, b: f32) -> f32 {
	libm::fdimf(a, b)
}

#[no_mangle]
pub extern "C" fn hypot(x: f64, y: f64) -> f64 {
	libm::hypot(x, y)
}

#[no_mangle]
pub extern "C" fn hypotf(x: f32, y: f32) -> f32 {
	libm::hypotf(x, y)
}

#[no_mangle]
pub extern "C" fn log(x: f64) -> f64 {
	libm::log(x)
}

#[no_mangle]
pub extern "C" fn log10(x: f64) -> f64 {
	libm::log10(x)
}

#[no_mangle]
pub extern "C" fn log10f(x: f32) -> f32 {
	libm::log10f(x)
}

#[no_mangle]
pub extern "C" fn logf(x: f32) -> f32 {
	libm::logf(x)
}

#[no_mangle]
pub extern "C" fn log1p(n: f64) -> f64 {
	libm::log1p(n)
}

#[no_mangle]
pub extern "C" fn log1pf(n: f32) -> f32 {
	libm::log1pf(n)
}

#[no_mangle]
pub extern "C" fn sinh(n: f64) -> f64 {
	libm::sinh(n)
}

#[no_mangle]
pub extern "C" fn sinhf(n: f32) -> f32 {
	libm::sinhf(n)
}

#[no_mangle]
pub extern "C" fn sqrt(x: f64) -> f64 {
	libm::sqrt(x)
}

#[no_mangle]
pub extern "C" fn sqrtf(x: f32) -> f32 {
	libm::sqrtf(x)
}

#[no_mangle]
pub extern "C" fn tan(n: f64) -> f64 {
	libm::tan(n)
}

#[no_mangle]
pub extern "C" fn tanf(n: f32) -> f32 {
	libm::tanf(n)
}

#[no_mangle]
pub extern "C" fn tanh(n: f64) -> f64 {
	libm::tanh(n)
}

#[no_mangle]
pub extern "C" fn tanhf(n: f32) -> f32 {
	libm::tanhf(n)
}

#[no_mangle]
pub extern "C" fn round(x: f64) -> f64 {
	libm::round(x)
}

#[no_mangle]
pub extern "C" fn pow(x: f64, y: f64) -> f64 {
	libm::pow(x, y)
}

#[no_mangle]
pub extern "C" fn powf(x: f32, y: f32) -> f32 {
	libm::powf(x, y)
}
<commit_msg>Add missing cmath functions<commit_after>#![allow(dead_code)]

#[no_mangle]
pub extern "C" fn acos(n: f64) -> f64 {
	libm::acos(n)
}

#[no_mangle]
pub extern "C" fn acosf(n: f32) -> f32 {
	libm::acosf(n)
}

#[no_mangle]
pub extern "C" fn acosh(x: f64) -> f64 {
	libm::acosh(x)
}

#[no_mangle]
pub extern "C" fn acoshf(x: f32) -> f32 {
	libm::acoshf(x)
}

#[no_mangle]
pub extern "C" fn asin(n: f64) -> f64 {
	libm::asin(n)
}

#[no_mangle]
pub extern "C" fn asinf(n: f32) -> f32 {
	libm::asinf(n)
}

#[no_mangle]
pub extern "C" fn asinh(x: f64) -> f64 {
	libm::asinh(x)
}

#[no_mangle]
pub extern "C" fn asinhf(x: f32) -> f32 {
	libm::asinhf(x)
}

#[no_mangle]
pub extern "C" fn atan(n: f64) -> f64 {
	libm::atan(n)
}

#[no_mangle]
pub extern "C" fn atan2(a: f64, b: f64) -> f64 {
	libm::atan2(a, b)
}

#[no_mangle]
pub extern "C" fn atan2f(a: f32, b: f32) -> f32 {
	libm::atan2f(a, b)
}

#[no_mangle]
pub extern "C" fn atanf(n: f32) -> f32 {
	libm::atanf(n)
}

#[no_mangle]
pub extern "C" fn atanh(x: f64) -> f64 {
	libm::atanh(x)
}

#[no_mangle]
pub extern "C" fn atanhf(x: f32) -> f32 {
	libm::atanhf(x)
}

#[no_mangle]
pub extern "C" fn cbrt(n: f64) -> f64 {
	libm::cbrt(n)
}

#[no_mangle]
pub extern "C" fn cbrtf(n: f32) -> f32 {
	libm::cbrtf(n)
}

#[no_mangle]
pub extern "C" fn ceil(x: f64) -> f64 {
	libm::ceil(x)
}

#[no_mangle]
pub extern "C" fn ceilf(x: f32) -> f32 {
	libm::ceilf(x)
}

#[no_mangle]
pub extern "C" fn copysign(x: f64, y: f64) -> f64 {
	libm::copysign(x, y)
}

#[no_mangle]
pub extern "C" fn copysignf(x: f32, y: f32) -> f32 {
	libm::copysignf(x, y)
}

#[no_mangle]
pub extern "C" fn cos(x: f64) -> f64 {
	libm::cos(x)
}

#[no_mangle]
pub extern "C" fn cosf(x: f32) -> f32 {
	libm::cosf(x)
}

#[no_mangle]
pub extern "C" fn cosh(x: f64) -> f64 {
	libm::cosh(x)
}

#[no_mangle]
pub extern "C" fn coshf(x: f32) -> f32 {
	libm::coshf(x)
}

#[no_mangle]
pub extern "C" fn erf(x: f64) -> f64 {
	libm::erf(x)
}

#[no_mangle]
pub extern "C" fn erfc(x: f64) -> f64 {
	libm::erfc(x)
}

#[no_mangle]
pub extern "C" fn erff(x: f32) -> f32 {
	libm::erff(x)
}

#[no_mangle]
pub extern "C" fn erfcf(x: f32) -> f32 {
	libm::erfcf(x)
}

#[no_mangle]
pub extern "C" fn exp(x: f64) -> f64 {
	libm::exp(x)
}

#[no_mangle]
pub extern "C" fn expf(x: f32) -> f32 {
	libm::expf(x)
}

#[no_mangle]
pub extern "C" fn exp2(x: f64) -> f64 {
	libm::exp2(x)
}

#[no_mangle]
pub extern "C" fn exp2f(x: f32) -> f32 {
	libm::exp2f(x)
}

#[no_mangle]
pub extern "C" fn exp10(x: f64) -> f64 {
	libm::exp10(x)
}

#[no_mangle]
pub extern "C" fn exp10f(x: f32) -> f32 {
	libm::exp10f(x)
}

#[no_mangle]
pub extern "C" fn expm1(n: f64) -> f64 {
	libm::expm1(n)
}

#[no_mangle]
pub extern "C" fn expm1f(n: f32) -> f32 {
	libm::expm1f(n)
}

#[no_mangle]
pub extern "C" fn fabs(n: f64) -> f64 {
	libm::fabs(n)
}

#[no_mangle]
pub extern "C" fn fabsf(n: f32) -> f32 {
	libm::expm1f(n)
}

#[no_mangle]
pub extern "C" fn fdim(a: f64, b: f64) -> f64 {
	libm::fdim(a, b)
}

#[no_mangle]
pub extern "C" fn fdimf(a: f32, b: f32) -> f32 {
	libm::fdimf(a, b)
}

#[no_mangle]
pub extern "C" fn floorf(x: f32) -> f32 {
	libm::floorf(x)
}

#[no_mangle]
pub extern "C" fn fma(x: f64, y: f64, z: f64) -> f64 {
	libm::fma(x, y, z)
}

#[no_mangle]
pub extern "C" fn fmaf(x: f32, y: f32, z: f32) -> f32 {
	libm::fmaf(x, y, z)
}

#[no_mangle]
pub extern "C" fn fmax(x: f64, y: f64) -> f64 {
	libm::fmax(x, y)
}

#[no_mangle]
pub extern "C" fn fmaxf(x: f32, y: f32) -> f32 {
	libm::fmaxf(x, y)
}

#[no_mangle]
pub extern "C" fn fmin(x: f64, y: f64) -> f64 {
	libm::fmin(x, y)
}

#[no_mangle]
pub extern "C" fn fminf(x: f32, y: f32) -> f32 {
	libm::fminf(x, y)
}

#[no_mangle]
pub extern "C" fn fmod(x: f64, y: f64) -> f64 {
	libm::fmod(x, y)
}

#[no_mangle]
pub extern "C" fn fmodf(x: f32, y: f32) -> f32 {
	libm::fmodf(x, y)
}

#[no_mangle]
pub extern "C" fn frexp(arg: f64, exp: *mut i32) -> f64 {
	let (mantissa, exponent) = libm::frexp(arg);
	unsafe { *exp = exponent; }
	mantissa
}

#[no_mangle]
pub extern "C" fn frexpf(arg: f32, exp: *mut i32) -> f32 {
	let (mantissa, exponent) = libm::frexpf(arg);
	unsafe { *exp = exponent; }
	mantissa
}

#[no_mangle]
pub extern "C" fn hypot(x: f64, y: f64) -> f64 {
	libm::hypot(x, y)
}

#[no_mangle]
pub extern "C" fn hypotf(x: f32, y: f32) -> f32 {
	libm::hypotf(x, y)
}

#[no_mangle]
pub extern "C" fn ilogb(x: f64) -> i32 {
	libm::ilogb(x)
}

#[no_mangle]
pub extern "C" fn ilogbf(x: f32) -> i32 {
	libm::ilogbf(x)
}

#[no_mangle]
pub extern "C" fn j0(x: f64) -> f64 {
	libm::j0(x)
}

#[no_mangle]
pub extern "C" fn j0f(x: f32) -> f32 {
	libm::j0f(x)
}

#[no_mangle]
pub extern "C" fn j1(x: f64) -> f64 {
	libm::j1(x)
}

#[no_mangle]
pub extern "C" fn j1f(x: f32) -> f32 {
	libm::j1f(x)
}

#[no_mangle]
pub extern "C" fn jn(n: i32, x: f64) -> f64 {
	libm::jn(n, x)
}

#[no_mangle]
pub extern "C" fn jnf(n: i32, x: f32) -> f32 {
	libm::jnf(n, x)
}

#[no_mangle]
pub extern "C" fn ldexp(x: f64, n: i32) -> f64 {
	libm::ldexp(x, n)
}

#[no_mangle]
pub extern "C" fn ldexpf(x: f32, n: i32) -> f32 {
	libm::ldexpf(x, n)
}

#[no_mangle]
pub extern "C" fn lgamma(x: f64) -> f64 {
	libm::lgamma(x)
}

#[no_mangle]
pub extern "C" fn lgammaf(x: f32) -> f32 {
	libm::lgammaf(x)
}

#[no_mangle]
pub extern "C" fn lgamma_r(x: f64, signp: *mut i32) -> f64 {
	let (lgamma, r) = libm::lgamma_r(x);
	unsafe { *signp = r; }
	lgamma
}

#[no_mangle]
pub extern "C" fn lgammaf_r(x: f32, signp: *mut i32) -> f32 {
	let (lgamma, r) = libm::lgammaf_r(x);
	unsafe { *signp = r; }
	lgamma
}

#[no_mangle]
pub extern "C" fn log(x: f64) -> f64 {
	libm::log(x)
}

#[no_mangle]
pub extern "C" fn log10(x: f64) -> f64 {
	libm::log10(x)
}

#[no_mangle]
pub extern "C" fn log10f(x: f32) -> f32 {
	libm::log10f(x)
}

#[no_mangle]
pub extern "C" fn logf(x: f32) -> f32 {
	libm::logf(x)
}

#[no_mangle]
pub extern "C" fn log2(x: f64) -> f64 {
	libm::log2(x)
}

#[no_mangle]
pub extern "C" fn log2f(x: f32) -> f32 {
	libm::log2f(x)
}

#[no_mangle]
pub extern "C" fn log1p(n: f64) -> f64 {
	libm::log1p(n)
}

#[no_mangle]
pub extern "C" fn log1pf(n: f32) -> f32 {
	libm::log1pf(n)
}

#[no_mangle]
pub extern "C" fn modf(x: f64, integer: *mut f64) -> f64 {
	let (frac_part, int_part) = libm::modf(x);
	unsafe { *integer = int_part; }
	frac_part
}

#[no_mangle]
pub extern "C" fn modff(x: f32, integer: *mut f32) -> f32 {
	let (frac_part, int_part) = libm::modff(x);
	unsafe { *integer = int_part; }
	frac_part
}

#[no_mangle]
pub extern "C" fn nextafter(x: f64, y: f64) -> f64 {
	libm::nextafter(x, y)
}

#[no_mangle]
pub extern "C" fn nextafterf(x: f32, y: f32) -> f32 {
	libm::nextafterf(x, y)
}

#[no_mangle]
pub extern "C" fn pow(x: f64, y: f64) -> f64 {
	libm::pow(x, y)
}

#[no_mangle]
pub extern "C" fn powf(x: f32, y: f32) -> f32 {
	libm::powf(x, y)
}

#[no_mangle]
pub extern "C" fn remainder(x: f64, y: f64) -> f64 {
	libm::remainder(x, y)
}

#[no_mangle]
pub extern "C" fn remainderf(x: f32, y: f32) -> f32 {
	libm::remainderf(x, y)
}

#[no_mangle]
pub extern "C" fn remquo(x: f64, y: f64, quotient: *mut i32) -> f64 {
	let (rem, quo) = libm::remquo(x, y);
	unsafe { *quotient = quo; }
	rem
}

#[no_mangle]
pub extern "C" fn remquof(x: f32, y: f32, quotient: *mut i32) -> f32 {
	let (rem, quo) = libm::remquof(x, y);
	unsafe { *quotient = quo; }
	rem
}

#[no_mangle]
pub extern "C" fn round(n: f64) -> f64 {
	libm::round(n)
}

#[no_mangle]
pub extern "C" fn roundf(n: f32) -> f32 {
	libm::roundf(n)
}

#[no_mangle]
pub extern "C" fn scalbn(x: f64, n: i32) -> f64 {
	libm::scalbn(x, n)
}

#[no_mangle]
pub extern "C" fn scalbnf(x: f32, n: i32) -> f32 {
	libm::scalbnf(x, n)
}

#[no_mangle]
pub extern "C" fn sin(n: f64) -> f64 {
	libm::sin(n)
}

#[no_mangle]
pub extern "C" fn sinf(n: f32) -> f32 {
	libm::sinf(n)
}

#[no_mangle]
pub extern "C" fn sincos(n: f64, sin: *mut f64, cos: *mut f64) {
	let (res_sin, res_cos) = libm::sincos(n);
	unsafe {
		*sin = res_sin;
		*cos = res_cos;
	}
}

#[no_mangle]
pub extern "C" fn sincosf(n: f32, sin: *mut f32, cos: *mut f32) {
	let (res_sin, res_cos) = libm::sincosf(n);
	unsafe {
		*sin = res_sin;
		*cos = res_cos;
	}
}

#[no_mangle]
pub extern "C" fn sinh(n: f64) -> f64 {
	libm::sinh(n)
}

#[no_mangle]
pub extern "C" fn sinhf(n: f32) -> f32 {
	libm::sinhf(n)
}

#[no_mangle]
pub extern "C" fn sqrt(x: f64) -> f64 {
	libm::sqrt(x)
}

#[no_mangle]
pub extern "C" fn sqrtf(x: f32) -> f32 {
	libm::sqrtf(x)
}

#[no_mangle]
pub extern "C" fn tan(n: f64) -> f64 {
	libm::tan(n)
}

#[no_mangle]
pub extern "C" fn tanf(n: f32) -> f32 {
	libm::tanf(n)
}

#[no_mangle]
pub extern "C" fn tanh(n: f64) -> f64 {
	libm::tanh(n)
}

#[no_mangle]
pub extern "C" fn tanhf(n: f32) -> f32 {
	libm::tanhf(n)
}

#[no_mangle]
pub extern "C" fn tgamma(n: f64) -> f64 {
	libm::tgamma(n)
}

#[no_mangle]
pub extern "C" fn tgammaf(n: f32) -> f32 {
	libm::tgammaf(n)
}

#[no_mangle]
pub extern "C" fn trunc(n: f64) -> f64 {
	libm::trunc(n)
}

#[no_mangle]
pub extern "C" fn truncf(n: f32) -> f32 {
	libm::truncf(n)
}

#[no_mangle]
pub extern "C" fn y0(n: f64) -> f64 {
	libm::y0(n)
}

#[no_mangle]
pub extern "C" fn y0f(n: f32) -> f32 {
	libm::y0f(n)
}

#[no_mangle]
pub extern "C" fn y1(n: f64) -> f64 {
	libm::y1(n)
}

#[no_mangle]
pub extern "C" fn y1f(n: f32) -> f32 {
	libm::y1f(n)
}

#[no_mangle]
pub extern "C" fn yn(n: i32, x: f64) -> f64 {
	libm::yn(n, x)
}

#[no_mangle]
pub extern "C" fn ynf(n: i32, x: f32) -> f32 {
	libm::ynf(n, x)
}
<|endoftext|>