<commit_before>//! A simple and type agnostic dual-quaternion math library designed for reexporting

extern crate vecmath;
extern crate quaternion;

use quaternion::Quaternion;
use vecmath::Vector3;
use vecmath::traits::Float;

/// A dual-quaternion consists of a real component and a dual component,
/// and can be used to represent both rotation and translation
pub type DualQuaternion<T> = (Quaternion<T>, Quaternion<T>);

/// Constructs identity dual-quaternion, representing no rotation or translation.
#[inline(always)]
pub fn id<T: Float>() -> DualQuaternion<T> {
    let one = T::one();
    let zero = T::zero();
    (
        (one, [zero, zero, zero]),
        (zero, [zero, zero, zero])
    )
}

/// Construct a dual-quaternion from separate rotation and translation components
#[inline(always)]
pub fn from_rotation_and_translation<T: Float>(rotation: Quaternion<T>, translation: Vector3<T>) -> DualQuaternion<T> {
    let zero = T::zero();
    let half = T::from_f64(0.5);
    (
        rotation,
        quaternion::scale(
            quaternion::mul((zero, translation), rotation),
            half
        )
    )
}

/// Adds two dual-quaternions
#[inline(always)]
pub fn add<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::add(a.0, b.0),
        quaternion::add(a.1, b.1)
    )
}

/// Multiplies two dual-quaternions
#[inline(always)]
pub fn mul<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::mul(b.0, a.0),
        quaternion::add(
            quaternion::mul(b.1, a.0),
            quaternion::mul(b.0, a.1)
        )
    )
}

/// Scales a dual-quaternion (element-wise) by a scalar
#[inline(always)]
pub fn scale<T: Float>(q: DualQuaternion<T>, t: T) -> DualQuaternion<T>
{
    (quaternion::scale(q.0, t), quaternion::scale(q.1, t))
}

/// Returns the dual-quaternion conjugate
#[inline(always)]
pub fn conj<T: Float>(q: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::conj(q.0),
        quaternion::conj(q.1)
    )
}

/// Dot product of two dual-quaternions
#[inline(always)]
pub fn dot<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> T {
    quaternion::dot(a.0, b.0)
}

/// Normalizes a dual-quaternion
pub fn normalize<T: Float>(q: DualQuaternion<T>) -> DualQuaternion<T> {
    let real_len_recip = T::one() / dot(q, q).sqrt();
    (
        quaternion::scale(q.0, real_len_recip),
        quaternion::add(
            quaternion::scale(q.1, real_len_recip),
            quaternion::scale(q.0, -quaternion::dot(q.0, q.1))
        )
    )
}

/// Extracts rotation component from a dual-quaternion
pub fn get_rotation<T: Float>(q: DualQuaternion<T>) -> Quaternion<T> {
    q.0
}

/// Extracts translation component from a dual-quaternion
pub fn get_translation<T: Float>(q: DualQuaternion<T>) -> Vector3<T> {
    let two = T::from_f64(2.0);
    let t = quaternion::mul(
        quaternion::scale(q.1, two),
        quaternion::conj(q.0)
    );
    t.1
}

/// Tests
#[cfg(test)]
mod test {

    use std::f32::consts::PI;
    use quaternion;
    use vecmath::Vector3;

    const EPSILON: f32 = 0.000001;

    #[test]
    fn test_construction_and_extraction() {
        let r = quaternion::euler_angles(PI, PI, PI);
        let t = [1.0, 2.0, 3.0];

        let dq = super::from_rotation_and_translation(r, t);

        let r_prime = super::get_rotation(dq);
        let t_prime = super::get_translation(dq);

        assert!((t_prime[0] - t[0]).abs() < EPSILON);
        assert!((t_prime[1] - t[1]).abs() < EPSILON);
        assert!((t_prime[2] - t[2]).abs() < EPSILON);

        assert!((r_prime.0 - r.0).abs() < EPSILON);
        assert!((r_prime.1[0] - r.1[0]).abs() < EPSILON);
        assert!((r_prime.1[1] - r.1[1]).abs() < EPSILON);
        assert!((r_prime.1[2] - r.1[2]).abs() < EPSILON);
    }

    #[test]
    fn test_mul_rotations() {

        let r1 = quaternion::euler_angles(PI / 2.0, PI, PI);
        let r2 = quaternion::euler_angles(PI / 2.0, -PI, 0.0);

        let t1 = [0.0, 0.0, 0.0];
        let t2 = [0.0, 0.0, 0.0];

        let dq1 = super::from_rotation_and_translation(r1, t1);
        let dq2 = super::from_rotation_and_translation(r2, t2);
        let dq3 = super::mul(dq1, dq2);

        let r_prime = super::get_rotation(dq3);
        let t_prime = super::get_translation(dq3);

        let r_expected = quaternion::euler_angles(PI, 0.0, PI);
        let t_expected = [0.0, 0.0, 0.0];

        assert!((t_prime[0] - t_expected[0]).abs() < EPSILON);
        assert!((t_prime[1] - t_expected[1]).abs() < EPSILON);
        assert!((t_prime[2] - t_expected[2]).abs() < EPSILON);

        let rotate_test_1 = quaternion::rotate_vector(r_prime, [1.0, 1.0, 1.0]);
        let rotate_test_2 = quaternion::rotate_vector(r_expected, [1.0, 1.0, 1.0]);

        assert!((rotate_test_1[0] - rotate_test_2[0]).abs() < EPSILON);
        assert!((rotate_test_1[1] - rotate_test_2[1]).abs() < EPSILON);
        assert!((rotate_test_1[2] - rotate_test_2[2]).abs() < EPSILON);

    }

    #[test]
    fn test_mul_translations() {

        let t1: Vector3<f32> = [1.0, 2.0, 3.0];
        let t2: Vector3<f32> = [1.0, -2.0, 0.0];

        let dq1 = super::from_rotation_and_translation(quaternion::id(), t1);
        let dq2 = super::from_rotation_and_translation(quaternion::id(), t2);
        let dq3 = super::mul(dq1, dq2);

        let r_prime = super::get_rotation(dq3);
        let t_prime = super::get_translation(dq3);

        let r_expected = quaternion::id();
        let t_expected = [2.0, 0.0, 3.0];

        assert!((t_prime[0] - t_expected[0]).abs() < EPSILON);
        assert!((t_prime[1] - t_expected[1]).abs() < EPSILON);
        assert!((t_prime[2] - t_expected[2]).abs() < EPSILON);

        let rotate_test_1 = quaternion::rotate_vector(r_prime, [1.0, 1.0, 1.0]);
        let rotate_test_2 = quaternion::rotate_vector(r_expected, [1.0, 1.0, 1.0]);

        assert!((rotate_test_1[0] - rotate_test_2[0]).abs() < EPSILON);
        assert!((rotate_test_1[1] - rotate_test_2[1]).abs() < EPSILON);
        assert!((rotate_test_1[2] - rotate_test_2[2]).abs() < EPSILON);

    }

    #[test]
    fn test_mul_conj() {
        let r = quaternion::euler_angles(PI, PI, PI);
        let t = [1.0, 2.0, 3.0];

        let dq = super::from_rotation_and_translation(r, t);
        let dq_conj = super::conj(dq);

        let dq_prime = super::mul(dq, dq_conj);
        let r_prime = super::get_rotation(dq_prime);
        let t_prime = super::get_translation(dq_prime);

        assert!((t_prime[0] - 0.0).abs() < EPSILON);
        assert!((t_prime[1] - 0.0).abs() < EPSILON);
        assert!((t_prime[2] - 0.0).abs() < EPSILON);

        assert!((r_prime.0 - 1.0).abs() < EPSILON);
        assert!((r_prime.1[0] - 0.0).abs() < EPSILON);
        assert!((r_prime.1[1] - 0.0).abs() < EPSILON);
        assert!((r_prime.1[2] - 0.0).abs() < EPSILON);
    }

}
<commit_msg>fixed `mul` ordering<commit_after>//! A simple and type agnostic dual-quaternion math library designed for reexporting

extern crate vecmath;
extern crate quaternion;

use quaternion::Quaternion;
use vecmath::Vector3;
use vecmath::traits::Float;

/// A dual-quaternion consists of a real component and a dual component,
/// and can be used to represent both rotation and translation
pub type DualQuaternion<T> = (Quaternion<T>, Quaternion<T>);

/// Constructs identity dual-quaternion, representing no rotation or translation.
#[inline(always)]
pub fn id<T: Float>() -> DualQuaternion<T> {
    let one = T::one();
    let zero = T::zero();
    (
        (one, [zero, zero, zero]),
        (zero, [zero, zero, zero])
    )
}

/// Construct a dual-quaternion from separate rotation and translation components
#[inline(always)]
pub fn from_rotation_and_translation<T: Float>(rotation: Quaternion<T>, translation: Vector3<T>) -> DualQuaternion<T> {
    let zero = T::zero();
    let half = T::from_f64(0.5);
    (
        rotation,
        quaternion::scale(
            quaternion::mul((zero, translation), rotation),
            half
        )
    )
}

/// Adds two dual-quaternions
#[inline(always)]
pub fn add<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::add(a.0, b.0),
        quaternion::add(a.1, b.1)
    )
}

/// Multiplies two dual-quaternions
#[inline(always)]
pub fn mul<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::mul(a.0, b.0),
        quaternion::add(
            quaternion::mul(a.0, b.1),
            quaternion::mul(a.1, b.0)
        )
    )
}

/// Scales a dual-quaternion (element-wise) by a scalar
#[inline(always)]
pub fn scale<T: Float>(q: DualQuaternion<T>, t: T) -> DualQuaternion<T>
{
    (quaternion::scale(q.0, t), quaternion::scale(q.1, t))
}

/// Returns the dual-quaternion conjugate
#[inline(always)]
pub fn conj<T: Float>(q: DualQuaternion<T>) -> DualQuaternion<T> {
    (
        quaternion::conj(q.0),
        quaternion::conj(q.1)
    )
}

/// Dot product of two dual-quaternions
#[inline(always)]
pub fn dot<T: Float>(a: DualQuaternion<T>, b: DualQuaternion<T>) -> T {
    quaternion::dot(a.0, b.0)
}

/// Normalizes a dual-quaternion
pub fn normalize<T: Float>(q: DualQuaternion<T>) -> DualQuaternion<T> {
    let real_len_recip = T::one() / dot(q, q).sqrt();
    (
        quaternion::scale(q.0, real_len_recip),
        quaternion::add(
            quaternion::scale(q.1, real_len_recip),
            quaternion::scale(q.0, -quaternion::dot(q.0, q.1))
        )
    )
}

/// Extracts rotation component from a dual-quaternion
pub fn get_rotation<T: Float>(q: DualQuaternion<T>) -> Quaternion<T> {
    q.0
}

/// Extracts translation component from a dual-quaternion
pub fn get_translation<T: Float>(q: DualQuaternion<T>) -> Vector3<T> {
    let two = T::from_f64(2.0);
    let t = quaternion::mul(
        quaternion::scale(q.1, two),
        quaternion::conj(q.0)
    );
    t.1
}

/// Tests
#[cfg(test)]
mod test {

    use std::f32::consts::PI;
    use quaternion;
    use vecmath::Vector3;

    const EPSILON: f32 = 0.000001;

    #[test]
    fn test_construction_and_extraction() {
        let r = quaternion::euler_angles(PI, PI, PI);
        let t = [1.0, 2.0, 3.0];

        let dq = super::from_rotation_and_translation(r, t);

        let r_prime = super::get_rotation(dq);
        let t_prime = super::get_translation(dq);

        assert!((t_prime[0] - t[0]).abs() < EPSILON);
        assert!((t_prime[1] - t[1]).abs() < EPSILON);
        assert!((t_prime[2] - t[2]).abs() < EPSILON);

        assert!((r_prime.0 - r.0).abs() < EPSILON);
        assert!((r_prime.1[0] - r.1[0]).abs() < EPSILON);
        assert!((r_prime.1[1] - r.1[1]).abs() < EPSILON);
        assert!((r_prime.1[2] - r.1[2]).abs() < EPSILON);
    }

    #[test]
    fn test_mul_rotations() {

        let r1 = quaternion::euler_angles(PI / 2.0, PI, PI);
        let r2 = quaternion::euler_angles(PI / 2.0, -PI, 0.0);

        let t1 = [0.0, 0.0, 0.0];
        let t2 = [0.0, 0.0, 0.0];

        let dq1 = super::from_rotation_and_translation(r1, t1);
        let dq2 = super::from_rotation_and_translation(r2, t2);
        let dq3 = super::mul(dq1, dq2);

        let r_prime = super::get_rotation(dq3);
        let t_prime = super::get_translation(dq3);

        let r_expected = quaternion::euler_angles(PI, 0.0, PI);
        let t_expected = [0.0, 0.0, 0.0];

        assert!((t_prime[0] - t_expected[0]).abs() < EPSILON);
        assert!((t_prime[1] - t_expected[1]).abs() < EPSILON);
        assert!((t_prime[2] - t_expected[2]).abs() < EPSILON);

        let rotate_test_1 = quaternion::rotate_vector(r_prime, [1.0, 1.0, 1.0]);
        let rotate_test_2 = quaternion::rotate_vector(r_expected, [1.0, 1.0, 1.0]);

        assert!((rotate_test_1[0] - rotate_test_2[0]).abs() < EPSILON);
        assert!((rotate_test_1[1] - rotate_test_2[1]).abs() < EPSILON);
        assert!((rotate_test_1[2] - rotate_test_2[2]).abs() < EPSILON);

    }

    #[test]
    fn test_mul_translations() {

        let t1: Vector3<f32> = [1.0, 2.0, 3.0];
        let t2: Vector3<f32> = [1.0, -2.0, 0.0];

        let dq1 = super::from_rotation_and_translation(quaternion::id(), t1);
        let dq2 = super::from_rotation_and_translation(quaternion::id(), t2);
        let dq3 = super::mul(dq1, dq2);

        let r_prime = super::get_rotation(dq3);
        let t_prime = super::get_translation(dq3);

        let r_expected = quaternion::id();
        let t_expected = [2.0, 0.0, 3.0];

        assert!((t_prime[0] - t_expected[0]).abs() < EPSILON);
        assert!((t_prime[1] - t_expected[1]).abs() < EPSILON);
        assert!((t_prime[2] - t_expected[2]).abs() < EPSILON);

        let rotate_test_1 = quaternion::rotate_vector(r_prime, [1.0, 1.0, 1.0]);
        let rotate_test_2 = quaternion::rotate_vector(r_expected, [1.0, 1.0, 1.0]);

        assert!((rotate_test_1[0] - rotate_test_2[0]).abs() < EPSILON);
        assert!((rotate_test_1[1] - rotate_test_2[1]).abs() < EPSILON);
        assert!((rotate_test_1[2] - rotate_test_2[2]).abs() < EPSILON);

    }

    #[test]
    fn test_mul_conj() {
        let r = quaternion::euler_angles(PI, PI, PI);
        let t = [1.0, 2.0, 3.0];

        let dq = super::from_rotation_and_translation(r, t);
        let dq_conj = super::conj(dq);

        let dq_prime = super::mul(dq, dq_conj);
        let r_prime = super::get_rotation(dq_prime);
        let t_prime = super::get_translation(dq_prime);

        assert!((t_prime[0] - 0.0).abs() < EPSILON);
        assert!((t_prime[1] - 0.0).abs() < EPSILON);
        assert!((t_prime[2] - 0.0).abs() < EPSILON);

        assert!((r_prime.0 - 1.0).abs() < EPSILON);
        assert!((r_prime.1[0] - 0.0).abs() < EPSILON);
        assert!((r_prime.1[1] - 0.0).abs() < EPSILON);
        assert!((r_prime.1[2] - 0.0).abs() < EPSILON);
    }

}
<|endoftext|>


<commit_before>//! Rustic bindings to [libnotify](https://developer.gnome.org/libnotify/)
//!
//! ```rust
//! extern crate libnotify;
//!
//! fn main() {
//!     // Create a libnotify context
//!     let notify = libnotify::Context::new("myapp").unwrap();
//!     // Create a new notification and show it
//!     let n = notify.new_notification("Summary",
//!                                     Some("Optional Body"),
//!                                     None).unwrap();
//!     n.show().unwrap();
//!     // You can also use the .show() convenience method on the context
//!     notify.show("I am another notification", None, None).unwrap();
//! }
//!
//! ```

#![warn(missing_docs)]

extern crate gdk_pixbuf;
extern crate gdk_pixbuf_sys;
extern crate glib;
extern crate glib_sys;
extern crate gtypes;
extern crate libnotify_sys as sys;

use gdk_pixbuf_sys::GdkPixbuf;
use glib::translate::*;
use gtypes::{TRUE, FALSE};
use std::error::Error;
use std::ffi::{self, CStr, CString};
use std::fmt;
use std::marker::PhantomData;
use std::os::raw::c_int;

/// The urgency level of the notification.
pub enum Urgency {
    /// Low urgency. Used for unimportant notifications.
    Low,
    /// Normal urgency. Used for most standard notifications.
    Normal,
    /// Critical urgency. Used for very important notifications.
    Critical,
}

impl From<sys::NotifyUrgency> for Urgency {
    fn from(urgency: sys::NotifyUrgency) -> Urgency {
        match urgency {
            sys::NotifyUrgency::NotifyUrgencyLow => Urgency::Low,
            sys::NotifyUrgency::NotifyUrgencyNormal => Urgency::Normal,
            sys::NotifyUrgency::NotifyUrgencyCritical => Urgency::Critical,
        }
    }
}

impl From<Urgency> for sys::NotifyUrgency {
    fn from(urgency: Urgency) -> sys::NotifyUrgency {
        match urgency {
            Urgency::Low => sys::NotifyUrgency::NotifyUrgencyLow,
            Urgency::Normal => sys::NotifyUrgency::NotifyUrgencyNormal,
            Urgency::Critical => sys::NotifyUrgency::NotifyUrgencyCritical,
        }
    }
}

/// Error that can happen on context creation
#[derive(Debug)]
pub enum ContextCreationError {
    /// Context already exists.
    AlreadyExists,
    /// Failed to initialize libnotify.
    InitError,
    /// A nul byte was found in the provided string.
    NulError(ffi::NulError),
}

impl fmt::Display for ContextCreationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use ContextCreationError::*;
        match *self {
            AlreadyExists => write!(f, "A Libnotify context already exists."),
            InitError => write!(f, "Failed to initialize libnotify."),
            NulError(ref e) => write!(f, "{}", e),
        }
    }
}

impl From<ffi::NulError> for ContextCreationError {
    fn from(src: ffi::NulError) -> Self {
        ContextCreationError::NulError(src)
    }
}

#[derive(Debug)]
/// An error that can happen when attempting to create a notification.
pub enum NotificationCreationError {
    /// A nul byte was found in the provided string.
    NulError(ffi::NulError),
    /// An unknown error happened.
    Unknown,
    /// Invalid parameter passed to a glib function
    InvalidParameter,
}

impl fmt::Display for NotificationCreationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use NotificationCreationError::*;
        match *self {
            NulError(ref e) => write!(f, "{}", e),
            Unknown => write!(f, "Unknown error"),
            InvalidParameter => write!(f, "An invalid parameter was passed"),
        }
    }
}

impl From<ffi::NulError> for NotificationCreationError {
    fn from(src: ffi::NulError) -> Self {
        NotificationCreationError::NulError(src)
    }
}

impl Error for NotificationCreationError {
    fn description(&self) -> &str {
        "notification creation error"
    }
}

/// The context which within libnotify operates.
///
/// Only one context can exist at a time.
pub struct Context;

impl Context {
    /// Create a new context
    ///
    /// Arguments:
    ///
    /// - app_name: The name of the application using the context
    pub fn new(app_name: &str) -> Result<Context, ContextCreationError> {
        unsafe {
            if sys::notify_is_initted() == TRUE {
                return Err(ContextCreationError::AlreadyExists);
            }
            let app_name = try!(CString::new(app_name));
            if sys::notify_init(app_name.as_ptr()) == FALSE {
                return Err(ContextCreationError::InitError);
            }
        }
        Ok(Context)
    }

    /// Creates a new Notification.
    ///
    /// Arguments:
    ///
    /// - summary: Required summary text
    /// - body: Optional body text
    /// - icon: Optional icon theme icon name or filename
    pub fn new_notification
        (&self,
         summary: &str,
         body: Option<&str>,
         icon: Option<&str>)
         -> Result<Notification, NotificationCreationError> {
        let summary = try!(CString::new(summary));
        let body = match body {
            Some(body) => Some(try!(CString::new(body))),
            None => None,
        };
        let body_ptr = match body {
            Some(ref body) => body.as_ptr(),
            None => std::ptr::null(),
        };
        let icon = match icon {
            Some(icon) => Some(try!(CString::new(icon))),
            None => None,
        };
        let icon_ptr = match icon {
            Some(ref icon) => icon.as_ptr(),
            None => std::ptr::null(),
        };

        unsafe {
            let n = sys::notify_notification_new(summary.as_ptr(),
                                                 body_ptr,
                                                 icon_ptr);
            if n.is_null() {
                return Err(NotificationCreationError::Unknown);
            }

            Ok(Notification {
                   handle: n,
                   _phantom: PhantomData,
               })
        }
    }

    /// Show a notification.
    ///
    /// This is a convenience method that creates a new notification,
    /// and shows it in one step.
    pub fn show(&self,
                summary: &str,
                body: Option<&str>,
                icon: Option<&str>)
                -> Result<(), Box<Error>> {
        let notif = try!(self.new_notification(summary, body, icon));
        try!(notif.show());
        Ok(())
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            sys::notify_uninit();
        }
    }
}

/// A passive pop-up notification
pub struct Notification<'a> {
    handle: *mut sys::NotifyNotification,
    _phantom: PhantomData<&'a Context>,
}

impl<'a> Notification<'a> {
    /// Tells the notification server to display the notification
    /// on the screen.
    pub fn show(&'a self) -> Result<(), NotificationShowError> {
        unsafe {
            let mut err: *mut glib_sys::GError = std::ptr::null_mut();
            sys::notify_notification_show(self.handle, &mut err);
            if !err.is_null() {
                let result = Err(NotificationShowError {
                                     message: CStr::from_ptr((*err).message)
                                         .to_string_lossy()
                                         .into_owned(),
                                 });
                glib_sys::g_error_free(err);
                return result;
            }
            Ok(())
        }
    }

    /// Set the notification timeout. Note that the server might ignore
    /// the timeout.
    pub fn set_notification_timeout(&self, timeout: i32) {
        let _timeout: c_int = From::from(timeout);

        unsafe { sys::notify_notification_set_timeout(self.handle, _timeout) }
    }

    /// Updates the notification text and icon. This won't send the update
    /// out and display it on the screen. For that, you will need to
    /// call `.show()`.
    pub fn update(&self,
                  summary: &str,
                  body: Option<&str>,
                  icon: Option<&str>)
                  -> Result<(), NotificationCreationError> {
        let summary = try!(CString::new(summary));
        let body = match body {
            Some(body) => Some(try!(CString::new(body))),
            None => None,
        };
        let body_ptr = match body {
            Some(ref body) => body.as_ptr(),
            None => std::ptr::null(),
        };
        let icon = match icon {
            Some(icon) => Some(try!(CString::new(icon))),
            None => None,
        };
        let icon_ptr = match icon {
            Some(ref icon) => icon.as_ptr(),
            None => std::ptr::null(),
        };

        unsafe {
            let b = sys::notify_notification_update(self.handle,
                                                    summary.as_ptr(),
                                                    body_ptr,
                                                    icon_ptr);
            if b == FALSE {
                return Err(NotificationCreationError::InvalidParameter);
            }
        }

        return Ok(());
    }

    /// Sets a hint for `key` with value `value`. If value is `None`,
    /// then key is unset.
    pub fn set_hint(&self,
                    key: &str,
                    value: Option<glib::variant::Variant>)
                    -> Result<(), NotificationCreationError> {
        let key = try!(CString::new(key));

        let gvalue: *mut glib_sys::GVariant = {
            match value {
                Some(ref value) => value.to_glib_none().0,
                None => std::ptr::null_mut(),
            }
        };

        unsafe {
            sys::notify_notification_set_hint(self.handle, key.as_ptr(), gvalue)
        }

        return Ok(());
    }

    /// Sets the category of this notification. This can be used by the
    /// notification server to filter or display the data in a certain way.
    pub fn set_category(&self, category: &str) -> Result<(), NotificationCreationError> {
        let category = try!(CString::new(category));
        unsafe {
            sys::notify_notification_set_category(self.handle,
                                                   category.as_ptr());
        }

        return Ok(());
    }

    /// Sets the urgency level of this notification.
    pub fn set_urgency(&self, urgency: Urgency) {
        let urgency: sys::NotifyUrgency = From::from(urgency);

        unsafe {
            sys::notify_notification_set_urgency(self.handle,
                                             urgency);
        }
    }

    /// Sets the image in the notification from a Pixbuf.
    pub fn set_image_from_pixbuf(&self, pixbuf: &gdk_pixbuf::Pixbuf) {
        let pixbuf: *mut GdkPixbuf = pixbuf.to_glib_none().0;

        unsafe {
            sys::notify_notification_set_image_from_pixbuf(self.handle,
                                                            pixbuf);
        }
    }

    /// Clears all hints from the notification.
    pub fn clear_hints(&self) {
        unsafe {
            sys::notify_notification_clear_hints(self.handle);
        }
    }
}

/// An error that can happen when attempting to show a notification.
#[derive(Debug)]
pub struct NotificationShowError {
    message: String,
}

impl fmt::Display for NotificationShowError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error showing notification: {}", self.message)
    }
}

impl Error for NotificationShowError {
    fn description(&self) -> &str {
        "notification show error"
    }
}
<commit_msg>Add Notification::close()<commit_after>//! Rustic bindings to [libnotify](https://developer.gnome.org/libnotify/)
//!
//! ```rust
//! extern crate libnotify;
//!
//! fn main() {
//!     // Create a libnotify context
//!     let notify = libnotify::Context::new("myapp").unwrap();
//!     // Create a new notification and show it
//!     let n = notify.new_notification("Summary",
//!                                     Some("Optional Body"),
//!                                     None).unwrap();
//!     n.show().unwrap();
//!     // You can also use the .show() convenience method on the context
//!     notify.show("I am another notification", None, None).unwrap();
//! }
//!
//! ```

#![warn(missing_docs)]

extern crate gdk_pixbuf;
extern crate gdk_pixbuf_sys;
extern crate glib;
extern crate glib_sys;
extern crate gtypes;
extern crate libnotify_sys as sys;

use gdk_pixbuf_sys::GdkPixbuf;
use glib::translate::*;
use gtypes::{TRUE, FALSE};
use std::error::Error;
use std::ffi::{self, CStr, CString};
use std::fmt;
use std::marker::PhantomData;
use std::os::raw::c_int;

/// The urgency level of the notification.
pub enum Urgency {
    /// Low urgency. Used for unimportant notifications.
    Low,
    /// Normal urgency. Used for most standard notifications.
    Normal,
    /// Critical urgency. Used for very important notifications.
    Critical,
}

impl From<sys::NotifyUrgency> for Urgency {
    fn from(urgency: sys::NotifyUrgency) -> Urgency {
        match urgency {
            sys::NotifyUrgency::NotifyUrgencyLow => Urgency::Low,
            sys::NotifyUrgency::NotifyUrgencyNormal => Urgency::Normal,
            sys::NotifyUrgency::NotifyUrgencyCritical => Urgency::Critical,
        }
    }
}

impl From<Urgency> for sys::NotifyUrgency {
    fn from(urgency: Urgency) -> sys::NotifyUrgency {
        match urgency {
            Urgency::Low => sys::NotifyUrgency::NotifyUrgencyLow,
            Urgency::Normal => sys::NotifyUrgency::NotifyUrgencyNormal,
            Urgency::Critical => sys::NotifyUrgency::NotifyUrgencyCritical,
        }
    }
}

/// Error that can happen on context creation
#[derive(Debug)]
pub enum ContextCreationError {
    /// Context already exists.
    AlreadyExists,
    /// Failed to initialize libnotify.
    InitError,
    /// A nul byte was found in the provided string.
    NulError(ffi::NulError),
}

impl fmt::Display for ContextCreationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use ContextCreationError::*;
        match *self {
            AlreadyExists => write!(f, "A Libnotify context already exists."),
            InitError => write!(f, "Failed to initialize libnotify."),
            NulError(ref e) => write!(f, "{}", e),
        }
    }
}

impl From<ffi::NulError> for ContextCreationError {
    fn from(src: ffi::NulError) -> Self {
        ContextCreationError::NulError(src)
    }
}

#[derive(Debug)]
/// An error that can happen when attempting to create a notification.
pub enum NotificationCreationError {
    /// A nul byte was found in the provided string.
    NulError(ffi::NulError),
    /// An unknown error happened.
    Unknown,
    /// Invalid parameter passed to a glib function
    InvalidParameter,
}

impl fmt::Display for NotificationCreationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use NotificationCreationError::*;
        match *self {
            NulError(ref e) => write!(f, "{}", e),
            Unknown => write!(f, "Unknown error"),
            InvalidParameter => write!(f, "An invalid parameter was passed"),
        }
    }
}

impl From<ffi::NulError> for NotificationCreationError {
    fn from(src: ffi::NulError) -> Self {
        NotificationCreationError::NulError(src)
    }
}

impl Error for NotificationCreationError {
    fn description(&self) -> &str {
        "notification creation error"
    }
}

/// The context which within libnotify operates.
///
/// Only one context can exist at a time.
pub struct Context;

impl Context {
    /// Create a new context
    ///
    /// Arguments:
    ///
    /// - app_name: The name of the application using the context
    pub fn new(app_name: &str) -> Result<Context, ContextCreationError> {
        unsafe {
            if sys::notify_is_initted() == TRUE {
                return Err(ContextCreationError::AlreadyExists);
            }
            let app_name = try!(CString::new(app_name));
            if sys::notify_init(app_name.as_ptr()) == FALSE {
                return Err(ContextCreationError::InitError);
            }
        }
        Ok(Context)
    }

    /// Creates a new Notification.
    ///
    /// Arguments:
    ///
    /// - summary: Required summary text
    /// - body: Optional body text
    /// - icon: Optional icon theme icon name or filename
    pub fn new_notification
        (&self,
         summary: &str,
         body: Option<&str>,
         icon: Option<&str>)
         -> Result<Notification, NotificationCreationError> {
        let summary = try!(CString::new(summary));
        let body = match body {
            Some(body) => Some(try!(CString::new(body))),
            None => None,
        };
        let body_ptr = match body {
            Some(ref body) => body.as_ptr(),
            None => std::ptr::null(),
        };
        let icon = match icon {
            Some(icon) => Some(try!(CString::new(icon))),
            None => None,
        };
        let icon_ptr = match icon {
            Some(ref icon) => icon.as_ptr(),
            None => std::ptr::null(),
        };

        unsafe {
            let n = sys::notify_notification_new(summary.as_ptr(),
                                                 body_ptr,
                                                 icon_ptr);
            if n.is_null() {
                return Err(NotificationCreationError::Unknown);
            }

            Ok(Notification {
                   handle: n,
                   _phantom: PhantomData,
               })
        }
    }

    /// Show a notification.
    ///
    /// This is a convenience method that creates a new notification,
    /// and shows it in one step.
    pub fn show(&self,
                summary: &str,
                body: Option<&str>,
                icon: Option<&str>)
                -> Result<(), Box<Error>> {
        let notif = try!(self.new_notification(summary, body, icon));
        try!(notif.show());
        Ok(())
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe {
            sys::notify_uninit();
        }
    }
}

/// A passive pop-up notification
pub struct Notification<'a> {
    handle: *mut sys::NotifyNotification,
    _phantom: PhantomData<&'a Context>,
}

impl<'a> Notification<'a> {
    /// Tells the notification server to display the notification
    /// on the screen.
    pub fn show(&'a self) -> Result<(), NotificationShowError> {
        unsafe {
            let mut err: *mut glib_sys::GError = std::ptr::null_mut();
            sys::notify_notification_show(self.handle, &mut err);
            if !err.is_null() {
                let result = Err(NotificationShowError {
                                     message: CStr::from_ptr((*err).message)
                                         .to_string_lossy()
                                         .into_owned(),
                                 });
                glib_sys::g_error_free(err);
                return result;
            }
            Ok(())
        }
    }

    /// Set the notification timeout. Note that the server might ignore
    /// the timeout.
    pub fn set_notification_timeout(&self, timeout: i32) {
        let _timeout: c_int = From::from(timeout);

        unsafe { sys::notify_notification_set_timeout(self.handle, _timeout) }
    }

    /// Updates the notification text and icon. This won't send the update
    /// out and display it on the screen. For that, you will need to
    /// call `.show()`.
    pub fn update(&self,
                  summary: &str,
                  body: Option<&str>,
                  icon: Option<&str>)
                  -> Result<(), NotificationCreationError> {
        let summary = try!(CString::new(summary));
        let body = match body {
            Some(body) => Some(try!(CString::new(body))),
            None => None,
        };
        let body_ptr = match body {
            Some(ref body) => body.as_ptr(),
            None => std::ptr::null(),
        };
        let icon = match icon {
            Some(icon) => Some(try!(CString::new(icon))),
            None => None,
        };
        let icon_ptr = match icon {
            Some(ref icon) => icon.as_ptr(),
            None => std::ptr::null(),
        };

        unsafe {
            let b = sys::notify_notification_update(self.handle,
                                                    summary.as_ptr(),
                                                    body_ptr,
                                                    icon_ptr);
            if b == FALSE {
                return Err(NotificationCreationError::InvalidParameter);
            }
        }

        return Ok(());
    }

    /// Sets a hint for `key` with value `value`. If value is `None`,
    /// then key is unset.
    pub fn set_hint(&self,
                    key: &str,
                    value: Option<glib::variant::Variant>)
                    -> Result<(), NotificationCreationError> {
        let key = try!(CString::new(key));

        let gvalue: *mut glib_sys::GVariant = {
            match value {
                Some(ref value) => value.to_glib_none().0,
                None => std::ptr::null_mut(),
            }
        };

        unsafe {
            sys::notify_notification_set_hint(self.handle, key.as_ptr(), gvalue)
        }

        return Ok(());
    }

    /// Sets the category of this notification. This can be used by the
    /// notification server to filter or display the data in a certain way.
    pub fn set_category(&self, category: &str) -> Result<(), NotificationCreationError> {
        let category = try!(CString::new(category));
        unsafe {
            sys::notify_notification_set_category(self.handle,
                                                   category.as_ptr());
        }

        return Ok(());
    }

    /// Sets the urgency level of this notification.
    pub fn set_urgency(&self, urgency: Urgency) {
        let urgency: sys::NotifyUrgency = From::from(urgency);

        unsafe {
            sys::notify_notification_set_urgency(self.handle,
                                             urgency);
        }
    }

    /// Sets the image in the notification from a Pixbuf.
    pub fn set_image_from_pixbuf(&self, pixbuf: &gdk_pixbuf::Pixbuf) {
        let pixbuf: *mut GdkPixbuf = pixbuf.to_glib_none().0;

        unsafe {
            sys::notify_notification_set_image_from_pixbuf(self.handle,
                                                            pixbuf);
        }
    }

    /// Clears all hints from the notification.
    pub fn clear_hints(&self) {
        unsafe {
            sys::notify_notification_clear_hints(self.handle);
        }
    }

    /// Synchronously tells the notification server to hide the
    /// notification on the screen.
    pub fn close(&self) -> Result<(), NotificationShowError> {
        unsafe {
            let mut err: *mut glib_sys::GError = std::ptr::null_mut();
            sys::notify_notification_close(self.handle,
                                           &mut err);

            if !err.is_null() {
                let result = Err(NotificationShowError {
                                     message: CStr::from_ptr((*err).message)
                                         .to_string_lossy()
                                         .into_owned(),
                                 });
                glib_sys::g_error_free(err);
                return result;
            }
        }
        return Ok(());
    }
}

/// An error that can happen when attempting to show a notification.
#[derive(Debug)]
pub struct NotificationShowError {
    message: String,
}

impl fmt::Display for NotificationShowError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error showing notification: {}", self.message)
    }
}

impl Error for NotificationShowError {
    fn description(&self) -> &str {
        "notification show error"
    }
}
<|endoftext|>


<commit_before>//! This crate contains a JPEG decoder.
//!
//! # Examples
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! let pixels = decoder.decode().expect("failed to decode image");
//! let metadata = decoder.info().unwrap();
//! ```
//!
//! Get metadata from a file without decoding it:
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! decoder.read_info().expect("failed to read metadata");
//! let metadata = decoder.info().unwrap();
//! ```

#![deny(missing_docs)]
#![deny(unsafe_code)]
#![cfg_attr(feature = "platform_independent", forbid(unsafe_code))]
#![cfg_attr(
    all(feature = "nightly_aarch64_neon", target_arch = "aarch64"),
    feature(aarch64_target_feature)
)]

extern crate alloc;
extern crate core;

#[cfg(feature = "rayon")]
extern crate rayon;

pub use decoder::{Decoder, ImageInfo, PixelFormat};
pub use error::{Error, UnsupportedFeature};
pub use parser::CodingProcess;

use std::io;

#[cfg(not(feature = "platform_independent"))]
mod arch;
mod decoder;
mod error;
mod huffman;
mod idct;
mod marker;
mod parser;
mod upsampler;
mod worker;

fn read_u8<R: io::Read>(reader: &mut R) -> io::Result<u8> {
    let mut buf = [0];
    reader.read_exact(&mut buf)?;
    Ok(buf[0])
}

fn read_u16_from_be<R: io::Read>(reader: &mut R) -> io::Result<u16> {
    let mut buf = [0, 0];
    reader.read_exact(&mut buf)?;
    Ok(u16::from_be_bytes(buf))
}
<commit_msg>Remove nightly qualification on neon<commit_after>//! This crate contains a JPEG decoder.
//!
//! # Examples
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! let pixels = decoder.decode().expect("failed to decode image");
//! let metadata = decoder.info().unwrap();
//! ```
//!
//! Get metadata from a file without decoding it:
//!
//! ```
//! use jpeg_decoder::Decoder;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file");
//! let mut decoder = Decoder::new(BufReader::new(file));
//! decoder.read_info().expect("failed to read metadata");
//! let metadata = decoder.info().unwrap();
//! ```

#![deny(missing_docs)]
#![deny(unsafe_code)]
#![cfg_attr(feature = "platform_independent", forbid(unsafe_code))]

extern crate alloc;
extern crate core;

#[cfg(feature = "rayon")]
extern crate rayon;

pub use decoder::{Decoder, ImageInfo, PixelFormat};
pub use error::{Error, UnsupportedFeature};
pub use parser::CodingProcess;

use std::io;

#[cfg(not(feature = "platform_independent"))]
mod arch;
mod decoder;
mod error;
mod huffman;
mod idct;
mod marker;
mod parser;
mod upsampler;
mod worker;

fn read_u8<R: io::Read>(reader: &mut R) -> io::Result<u8> {
    let mut buf = [0];
    reader.read_exact(&mut buf)?;
    Ok(buf[0])
}

fn read_u16_from_be<R: io::Read>(reader: &mut R) -> io::Result<u16> {
    let mut buf = [0, 0];
    reader.read_exact(&mut buf)?;
    Ok(u16::from_be_bytes(buf))
}
<|endoftext|>


<commit_before>/*!
A basic library for finding primes, using the Sieve of Eratosthenes. This library provides methods
for generating primes, testing whether a number is prime, and factorizing numbers. Most methods
generate primes lazily, so only enough primes will be generated for the given test, and primes are
cached for later use.

To use, see `PrimeSet`, a class which handles the Sieve and has multiple methods for iterating
over primes.

This also provides a few functions unconnected to `PrimeSet`, which will be faster for the first case,
but slower in the long term as they do not use any caching of primes.
*/

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unused_qualifications)]
#[warn(non_upper_case_globals)]
#[warn(missing_docs)]

#[cfg(test)]
extern crate test;

use std::ops::Index;
use std::slice;
use std::iter;
use std::num::Float;

#[cfg(test)]
use test::Bencher;

fn sqrt_floor(n : uint) -> uint {
    (n as f64).sqrt().floor() as uint
}

/** A prime generator, using the Sieve of Eratosthenes.

Create with `let mut pset = PrimeSet::new()`, and then use `pset.iter()` to iterate over all primes.
**/
pub struct PrimeSet {
    lst : Vec<uint>
}

/// An iterator over generated primes. Created by PrimeSet::iter or
/// PrimeSet::generator
pub struct PrimeSetIter<'a> {
    p : &'a mut PrimeSet,
    n : uint,
    expand : bool
}

impl PrimeSet {
    /// A new prime generator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet{lst:vec!(2,3)}
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l = self.lst[self.lst.len()-1] + 2;
        let mut sql = sqrt_floor(l);
        let mut remainder = 0;
        loop {
            for &n in self.lst.iter() {
                remainder = l % n;
                if remainder == 0 || n > sql {
                    break;
                }
            };

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
            sql = sqrt_floor(l);
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> uint {
        self.lst.len()
    }

    /// Return all primes found so far as a slice
    pub fn list<'a>(&'a self) -> &'a [uint] {
        self.lst.as_slice()
    }

    /// Iterator over all primes not yet found
    pub fn generator<'a>(&'a mut self) -> PrimeSetIter<'a> {
        let myn = self.len();
        PrimeSetIter{p:self, n:myn, expand:true}
    }

    /// Iterator over all primes, starting with 2. If you don't care about the "state" of the
    /// PrimeSet, this is what you want!
    pub fn iter<'a>(&'a mut self) -> PrimeSetIter<'a> {
        PrimeSetIter{p:self, n:0, expand:true}
    }

    //~ pub fn iter_once(&'self mut self) -> PrimeSetIter<'self> {
        //~ PrimeSetIter{p:self, n:0, expand:false}
    //~ }

    /// Iterator over just the primes found so far
    pub fn iter_vec<'a>(&'a self) -> slice::Items<'a, uint> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find(&mut self, n: uint) -> (uint, uint) {
        while n > *(self.lst.last().unwrap_or(&0)){
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    /// Note that this only requires primes up to n.sqrt() to be generated, and will generate
    /// them as necessary on its own.
    pub fn is_prime(&mut self, n: uint) -> bool {
        if n <= 1 {return false;}
        if n == 2 {return true;} // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {return false;};
            if m*m > n {return true;};
        }
        panic!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find_vec(&self, n: uint) -> Option<(uint, uint)> {
        if n > *(self.lst.last().unwrap_or(&0)){ return None;}

        let mut base : uint = 0;
        let mut lim : uint = self.len();

        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => ()
            }
            lim >>= 1;
        }
        return Some((base, self.lst[base]));
    }

    /// Get the nth prime, even if we haven't yet found it
    pub fn get(&mut self, index : &uint) -> &uint {
		for _ in range(0, (*index as int) + 1 - (self.lst.len() as int)){
			self.expand();
		}
        self.lst.index(index)
	}

	/// Get the prime factors of a number, starting from 2, including repeats
	pub fn prime_factors(&mut self, n: uint) -> Vec<uint> {
		if n == 1 {return Vec::new();}
		let mut curn = n;
		let mut m = ((curn as f64).sqrt()).ceil() as uint;
		let mut lst: Vec<uint> = Vec::new();
		for p in self.iter() {
			while curn % p == 0 {
				lst.push(p);
				curn /= p;
				if curn == 1 {return lst;}
				m = ((curn as f64).sqrt()).ceil() as uint;
			}

			if p > m {
				lst.push(p);
				return lst;
			}
		}
		panic!("This should be unreachable.");
	}
}

impl Index<uint, uint> for PrimeSet {
    fn index(&self, index: &uint) -> &uint {
        self.lst.index(index)
    }
}

impl<'a> Iterator<uint> for PrimeSetIter<'a> {
    fn next(&mut self) -> Option<uint> {
        while self.n >= self.p.len(){
            match self.expand {
                true => self.p.expand(),
                false => return None
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n-1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: uint) -> uint {
    let m = ((x as f64).sqrt()).ceil() as uint;
    if x % 2 == 0 { return 2; };
    for n in iter::range_step(3, m + 1, 2) {
        if x % n == 0 { return n; };
    }
    return x;
}

/// Find all prime factors of a number
/// Does not use a PrimeSet, but simply counts upwards
pub fn factors(x: uint) -> Vec<uint> {
    if x <= 1 {return vec!()};
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst.push(m);
        if m == curn { break  } else { curn /= m };
    }
    return lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst.push(m);
        if curn == m { break ; }
        while curn % m == 0 { curn /= m; }
        if curn == 1 { break ; }
    }
    return lst
}

/// Test whether a number is prime. Checks every odd number up to sqrt(n).
pub fn is_prime(n : uint) -> bool {
    if n <= 1 {return false;}
    firstfac(n) == n
}

#[test]
fn test_iter(){
    let mut pset = PrimeSet::new();
    let first_few = [2u,3,5,7,11,13,17,19,23];
    for (m, &n) in pset.iter().zip(first_few.iter()) {
        assert_eq!(m, n);
    }
}

#[test]
fn test_primes(){
    let mut pset = PrimeSet::new();

    // note: some are repeated, because the pset list grows as it goes

    assert!(!pset.is_prime(1));
    assert!(!is_prime(1));
    assert!(pset.is_prime(2));
    assert!(is_prime(2));
    assert!(pset.is_prime(13));
    assert!(is_prime(13));
    assert!(!pset.is_prime(45));
    assert!(!is_prime(45));
    assert!(!pset.is_prime(13*13));
    assert!(!is_prime(13*13));
    assert!(pset.is_prime(13));
    assert!(pset.is_prime(7));
    assert!(is_prime(7));
    assert!(!pset.is_prime(9));
    assert!(!is_prime(9));
    assert!(pset.is_prime(5));
    assert!(is_prime(5));
}

#[test]
fn test_factors(){
	let mut pset = PrimeSet::new();

	let ns = [  (1, vec!()),
                (2, vec!(2)),
                (3, vec!(3)),
                (4, vec!(2,2)),
                (5, vec!(5)),
                (6, vec!(2,3)),
	            (9, vec!(3,3)),
	            (12, vec!(2,2,3)),
	            (121, vec!(11,11)),
	            (144, vec!(2,2,2,2,3,3)),
	            (10_000_000, vec!(2,2,2,2,2,2,2,5,5,5,5,5,5,5)),
                (100, vec!(2,2,5,5)),
                (121, vec!(11, 11)),
                ];

    for &(n, ref v) in ns.iter(){
        assert_eq!(pset.prime_factors(n), *v);
        assert_eq!(factors(n), *v);
    }

	pset = PrimeSet::new();
	assert_eq!(pset.prime_factors(12), vec!(2,2,3));

}

#[bench]
fn bench_primes(b : &mut Bencher){
	b.iter(|| {
		let mut pset = PrimeSet::new();
		 let (_, _) = pset.find(1_000_000);
		 //~ let (idx, n) = pset.find(1_000_000);
		 //~ println!("Prime {}: {}", idx, n);
		 })
}
<commit_msg>Updated to newest rust<commit_after>/*!
A basic library for finding primes, using the Sieve of Eratosthenes. This library provides methods
for generating primes, testing whether a number is prime, and factorizing numbers. Most methods
generate primes lazily, so only enough primes will be generated for the given test, and primes are
cached for later use.

To use, see `PrimeSet`, a class which handles the Sieve and has multiple methods for iterating
over primes.

This also provides a few functions unconnected to `PrimeSet`, which will be faster for the first case,
but slower in the long term as they do not use any caching of primes.
*/

#[warn(non_camel_case_types)]
#[warn(non_snake_case)]
#[warn(unused_qualifications)]
#[warn(non_upper_case_globals)]
#[warn(missing_docs)]

#[cfg(test)]
extern crate test;

use std::ops::Index;
use std::slice;
use std::iter;
use std::num::Float;

#[cfg(test)]
use test::Bencher;

fn sqrt_floor(n : uint) -> uint {
    (n as f64).sqrt().floor() as uint
}

/** A prime generator, using the Sieve of Eratosthenes.

Create with `let mut pset = PrimeSet::new()`, and then use `pset.iter()` to iterate over all primes.
**/
pub struct PrimeSet {
    lst : Vec<uint>
}

/// An iterator over generated primes. Created by PrimeSet::iter or
/// PrimeSet::generator
pub struct PrimeSetIter<'a> {
    p : &'a mut PrimeSet,
    n : uint,
    expand : bool
}

impl PrimeSet {
    /// A new prime generator, primed with 2 and 3
    pub fn new() -> PrimeSet {
        PrimeSet{lst:vec!(2,3)}
    }

    /// Finds one more prime, and adds it to the list
    pub fn expand(&mut self) {
        let mut l = self.lst[self.lst.len()-1] + 2;
        let mut sql = sqrt_floor(l);
        let mut remainder = 0;
        loop {
            for &n in self.lst.iter() {
                remainder = l % n;
                if remainder == 0 || n > sql {
                    break;
                }
            };

            if remainder != 0 {
                self.lst.push(l);
                break;
            };

            l += 2;
            sql = sqrt_floor(l);
        }
    }

    /// Number of primes found so far
    pub fn len(&self) -> uint {
        self.lst.len()
    }

    /// Return all primes found so far as a slice
    pub fn list<'a>(&'a self) -> &'a [uint] {
        self.lst.as_slice()
    }

    /// Iterator over all primes not yet found
    pub fn generator<'a>(&'a mut self) -> PrimeSetIter<'a> {
        let myn = self.len();
        PrimeSetIter{p:self, n:myn, expand:true}
    }

    /// Iterator over all primes, starting with 2. If you don't care about the "state" of the
    /// PrimeSet, this is what you want!
    pub fn iter<'a>(&'a mut self) -> PrimeSetIter<'a> {
        PrimeSetIter{p:self, n:0, expand:true}
    }

    //~ pub fn iter_once(&'self mut self) -> PrimeSetIter<'self> {
        //~ PrimeSetIter{p:self, n:0, expand:false}
    //~ }

    /// Iterator over just the primes found so far
    pub fn iter_vec<'a>(&'a self) -> slice::Iter<'a, uint> {
        self.lst.iter()
    }

    /// Find the next largest prime from a number
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find(&mut self, n: uint) -> (uint, uint) {
        while n > *(self.lst.last().unwrap_or(&0)){
            self.expand();
        }
        self.find_vec(n).unwrap()
    }

    /// Check if a number is prime
    /// Note that this only requires primes up to n.sqrt() to be generated, and will generate
    /// them as necessary on its own.
    pub fn is_prime(&mut self, n: uint) -> bool {
        if n <= 1 {return false;}
        if n == 2 {return true;} // otherwise we get 2 % 2 == 0!
        for m in self.iter() {
            if n % m == 0 {return false;};
            if m*m > n {return true;};
        }
        panic!("This iterator should not be empty.");
    }

    /// Find the next largest prime from a number, if it is within the already-found list
    /// Returns (idx, prime)
    /// Note that if n is prime, then the output will be (idx, n)
    pub fn find_vec(&self, n: uint) -> Option<(uint, uint)> {
        if n > *(self.lst.last().unwrap_or(&0)){ return None;}

        let mut base : uint = 0;
        let mut lim : uint = self.len();

        while lim != 0 {
            let ix = base + (lim >> 1);
            match self.lst[ix].cmp(&n) {
                Equal => return Some((ix, self.lst[ix])),
                Less => {
                    base = ix + 1;
                    lim -= 1;
                }
                Greater => ()
            }
            lim >>= 1;
        }
        return Some((base, self.lst[base]));
    }

    /// Get the nth prime, even if we haven't yet found it
    pub fn get(&mut self, index : &uint) -> &uint {
		for _ in range(0, (*index as int) + 1 - (self.lst.len() as int)){
			self.expand();
		}
        self.lst.index(index)
	}

	/// Get the prime factors of a number, starting from 2, including repeats
	pub fn prime_factors(&mut self, n: uint) -> Vec<uint> {
		if n == 1 {return Vec::new();}
		let mut curn = n;
		let mut m = ((curn as f64).sqrt()).ceil() as uint;
		let mut lst: Vec<uint> = Vec::new();
		for p in self.iter() {
			while curn % p == 0 {
				lst.push(p);
				curn /= p;
				if curn == 1 {return lst;}
				m = ((curn as f64).sqrt()).ceil() as uint;
			}

			if p > m {
				lst.push(p);
				return lst;
			}
		}
		panic!("This should be unreachable.");
	}
}

impl Index<uint, uint> for PrimeSet {
    fn index(&self, index: &uint) -> &uint {
        self.lst.index(index)
    }
}

impl<'a> Iterator<uint> for PrimeSetIter<'a> {
    fn next(&mut self) -> Option<uint> {
        while self.n >= self.p.len(){
            match self.expand {
                true => self.p.expand(),
                false => return None
            }
        }
        self.n += 1;

        let m = self.p.lst[self.n-1];

        Some(m)
    }
}

/// Find the first factor (other than 1) of a number
fn firstfac(x: uint) -> uint {
    let m = ((x as f64).sqrt()).ceil() as uint;
    if x % 2 == 0 { return 2; };
    for n in iter::range_step(3, m + 1, 2) {
        if x % n == 0 { return n; };
    }
    return x;
}

/// Find all prime factors of a number
/// Does not use a PrimeSet, but simply counts upwards
pub fn factors(x: uint) -> Vec<uint> {
    if x <= 1 {return vec!()};
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst.push(m);
        if m == curn { break  } else { curn /= m };
    }
    return lst
}

/// Find all unique prime factors of a number
pub fn factors_uniq(x: uint) -> Vec<uint> {
    let mut lst: Vec<uint> = Vec::new();
    let mut curn = x;
    loop  {
        let m = firstfac(curn);
        lst.push(m);
        if curn == m { break ; }
        while curn % m == 0 { curn /= m; }
        if curn == 1 { break ; }
    }
    return lst
}

/// Test whether a number is prime. Checks every odd number up to sqrt(n).
pub fn is_prime(n : uint) -> bool {
    if n <= 1 {return false;}
    firstfac(n) == n
}

#[test]
fn test_iter(){
    let mut pset = PrimeSet::new();
    let first_few = [2u,3,5,7,11,13,17,19,23];
    for (m, &n) in pset.iter().zip(first_few.iter()) {
        assert_eq!(m, n);
    }
}

#[test]
fn test_primes(){
    let mut pset = PrimeSet::new();

    // note: some are repeated, because the pset list grows as it goes

    assert!(!pset.is_prime(1));
    assert!(!is_prime(1));
    assert!(pset.is_prime(2));
    assert!(is_prime(2));
    assert!(pset.is_prime(13));
    assert!(is_prime(13));
    assert!(!pset.is_prime(45));
    assert!(!is_prime(45));
    assert!(!pset.is_prime(13*13));
    assert!(!is_prime(13*13));
    assert!(pset.is_prime(13));
    assert!(pset.is_prime(7));
    assert!(is_prime(7));
    assert!(!pset.is_prime(9));
    assert!(!is_prime(9));
    assert!(pset.is_prime(5));
    assert!(is_prime(5));
}

#[test]
fn test_factors(){
	let mut pset = PrimeSet::new();

	let ns = [  (1, vec!()),
                (2, vec!(2)),
                (3, vec!(3)),
                (4, vec!(2,2)),
                (5, vec!(5)),
                (6, vec!(2,3)),
	            (9, vec!(3,3)),
	            (12, vec!(2,2,3)),
	            (121, vec!(11,11)),
	            (144, vec!(2,2,2,2,3,3)),
	            (10_000_000, vec!(2,2,2,2,2,2,2,5,5,5,5,5,5,5)),
                (100, vec!(2,2,5,5)),
                (121, vec!(11, 11)),
                ];

    for &(n, ref v) in ns.iter(){
        assert_eq!(pset.prime_factors(n), *v);
        assert_eq!(factors(n), *v);
    }

	pset = PrimeSet::new();
	assert_eq!(pset.prime_factors(12), vec!(2,2,3));

}

#[bench]
fn bench_primes(b : &mut Bencher){
	b.iter(|| {
		let mut pset = PrimeSet::new();
		 let (_, _) = pset.find(1_000_000);
		 //~ let (idx, n) = pset.find(1_000_000);
		 //~ println!("Prime {}: {}", idx, n);
		 })
}
<|endoftext|>


<commit_before>extern crate iron;

extern crate r2d2;
extern crate r2d2_postgres;
extern crate postgres;

use iron::prelude::*;
use iron::{typemap, BeforeMiddleware};

use std::sync::Arc;
use std::default::Default;
use postgres::{SslMode};
use r2d2_postgres::PostgresPoolManager;

pub struct PostgresMiddleware {
  pub pool: Arc<r2d2::Pool<postgres::Connection, r2d2_postgres::Error,
    r2d2_postgres::PostgresPoolManager, r2d2::LoggingErrorHandler>>,
}

struct Value(Arc<r2d2::Pool<postgres::Connection, r2d2_postgres::Error,
          r2d2_postgres::PostgresPoolManager, r2d2::LoggingErrorHandler>>);

impl typemap::Key for PostgresMiddleware { type Value = Value; }

impl PostgresMiddleware {
  pub fn new(pg_connection_str: &str) -> PostgresMiddleware {
    let config = Default::default();
    let manager = PostgresPoolManager::new(pg_connection_str, SslMode::None);
    let error_handler = r2d2::LoggingErrorHandler;
    let pool = Arc::new(r2d2::Pool::new(config, manager, error_handler).unwrap());
    PostgresMiddleware {
      pool: pool,
    }
  }
}

impl BeforeMiddleware for PostgresMiddleware {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<PostgresMiddleware>(Value(self.pool.clone()));
        Ok(())
    }
}

pub trait PostgresReqExt {
  fn db_conn(&self) -> r2d2::PooledConnection<postgres::Connection, r2d2_postgres::Error,
    r2d2_postgres::PostgresPoolManager, r2d2::LoggingErrorHandler>;
}

impl PostgresReqExt for Request {
  fn db_conn(&self) -> r2d2::PooledConnection<postgres::Connection, r2d2_postgres::Error,
    r2d2_postgres::PostgresPoolManager, r2d2::LoggingErrorHandler> {
    let poll_value = self.extensions.get::<PostgresMiddleware>().unwrap();
    let &Value(ref poll) = poll_value;

    return poll.get().unwrap();
  }
}
<commit_msg>Fixes for r2d2 changes<commit_after>extern crate iron;

extern crate r2d2;
extern crate r2d2_postgres;
extern crate postgres;

use iron::prelude::*;
use iron::{typemap, BeforeMiddleware};

use std::sync::Arc;
use std::default::Default;
use postgres::{SslMode};
use r2d2_postgres::PostgresConnectionManager;

pub struct PostgresMiddleware {
  pub pool: Arc<r2d2::Pool<r2d2_postgres::PostgresConnectionManager, r2d2::LoggingErrorHandler>>,
}

struct Value(Arc<r2d2::Pool<r2d2_postgres::PostgresConnectionManager, r2d2::LoggingErrorHandler>>);

impl typemap::Key for PostgresMiddleware { type Value = Value; }

impl PostgresMiddleware {
  pub fn new(pg_connection_str: &str) -> PostgresMiddleware {
    let config = Default::default();
    let manager = PostgresConnectionManager::new(pg_connection_str, SslMode::None);
    let error_handler = r2d2::LoggingErrorHandler;
    let pool = Arc::new(r2d2::Pool::new(config, manager, error_handler).unwrap());
    PostgresMiddleware {
      pool: pool,
    }
  }
}

impl BeforeMiddleware for PostgresMiddleware {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions.insert::<PostgresMiddleware>(Value(self.pool.clone()));
        Ok(())
    }
}

pub trait PostgresReqExt {
  fn db_conn(&self) -> r2d2::PooledConnection<r2d2_postgres::PostgresConnectionManager,
    r2d2::LoggingErrorHandler>;
}

impl PostgresReqExt for Request {
  fn db_conn(&self) -> r2d2::PooledConnection<r2d2_postgres::PostgresConnectionManager,
    r2d2::LoggingErrorHandler> {
    let poll_value = self.extensions.get::<PostgresMiddleware>().unwrap();
    let &Value(ref poll) = poll_value;

    return poll.get().unwrap();
  }
}
<|endoftext|>


<commit_before>extern crate cookie as _cookie;
#[macro_use] extern crate error_chain;
extern crate iron;
extern crate rand;
#[cfg(feature = "redis-backend")] extern crate redis;
#[cfg(feature = "redis-backend")] extern crate r2d2;
#[cfg(feature = "redis-backend")] extern crate r2d2_redis;

use iron::prelude::*;
use iron::middleware::{AroundMiddleware,Handler};
use iron::typemap;

pub mod backends;
pub mod errors;

/// Re-export of the cookie crate
pub mod cookie {
    pub use _cookie::*;
}

/// A simple key-value storage interface that is internally used by `Session`. After request
/// handling the `write` method is called where the session backend has the chance to e.g. set
/// cookies or otherwise modify the response.
pub trait RawSession {
    fn get_raw(&self, key: &str) -> IronResult<Option<String>>;
    fn set_raw(&mut self, key: &str, value: String) -> IronResult<()>;
    fn clear(&mut self) -> IronResult<()>;
    fn write(&self, response: &mut Response) -> IronResult<()>;
}

pub trait SessionBackend: Send + Sync + 'static {
    type S: RawSession;

    /// Parse the session before request handling and return the data in parsed form.
    fn from_request(&self, request: &mut Request) -> Self::S;
}

/// The most important type, the middleware you need to register.
///
/// First parameter is a session backend, which determines how your session data is actually
/// stored. Depending on whether you store your data clientside (signed cookies) or serverside
/// (e.g. Redis and a session key) you're going to have different security properties.
pub struct SessionStorage<B: SessionBackend> {
    backend: B
}

impl<B: SessionBackend> SessionStorage<B> {
    pub fn new(backend: B) -> Self {
        SessionStorage {
            backend: backend
        }
    }
}

/// The high-level interface you use to modify session data. You obtain this object with
/// `request.session()`.
pub struct Session {
    inner: Box<RawSession>,
    has_changed: bool,
}

impl Session {
    fn new(s: Box<RawSession>) -> Self {
        Session {
            inner: s,
            has_changed: false
        }
    }
}

/// A typed interface to the string-to-string mapping. Each type represents a key, each instance of
/// a type can be serialized into a value.
pub trait Value: Sized + 'static {
    fn get_key() -> &'static str;
    fn into_raw(self) -> String;
    fn from_raw(value: String) -> Option<Self>;
}

impl Session {
    /// Get a `Value` from the session.
    pub fn get<T: Value + Sized + 'static>(&self) -> IronResult<Option<T>> {
        Ok(try!(self.inner.get_raw(T::get_key())).and_then(T::from_raw))
    }

    /// Set a `Value` in the session.
    pub fn set<T: Value>(&mut self, t: T) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.set_raw(T::get_key(), t.into_raw())
    }

    /// Clear/delete the session
    pub fn clear(&mut self) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.clear()
    }
}

struct SessionKey;
impl typemap::Key for SessionKey { type Value = Session; }

impl<B: SessionBackend> AroundMiddleware for SessionStorage<B> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(move |req: &mut Request| -> IronResult<Response> {
            let s = self.backend.from_request(req);
            req.extensions.insert::<SessionKey>(Session::new(Box::new(s)));
            let mut res = handler.handle(req);
            let s = req.extensions.remove::<SessionKey>().unwrap();
            if s.has_changed {
                match res {
                    Ok(ref mut r) => try!(s.inner.write(r)),
                    Err(ref mut e) => try!(s.inner.write(&mut e.response))
                }
            };
            res
        })
    }
}

/// The helper trait to obtain your session data from a request.
pub trait SessionRequestExt {
    fn session(&mut self) -> &mut Session;
}

impl<'a, 'b> SessionRequestExt for Request<'a, 'b> {
    fn session(&mut self) -> &mut Session {
        self.extensions.get_mut::<SessionKey>().unwrap()
    }
}

fn get_default_cookie(key: String, value: String) -> cookie::Cookie {
    let mut rv = cookie::Cookie::new(key, value);
    rv.httponly = true;
    rv.path = Some("/".to_owned());
    rv
}

/// A module with some important traits to star-import.
pub mod traits {
    pub use super::{SessionRequestExt};
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Revert "Fix unused warning"<commit_after>extern crate cookie as _cookie;
#[macro_use] extern crate error_chain;
#[macro_use] extern crate iron;
extern crate rand;
#[cfg(feature = "redis-backend")] extern crate redis;
#[cfg(feature = "redis-backend")] extern crate r2d2;
#[cfg(feature = "redis-backend")] extern crate r2d2_redis;

use iron::prelude::*;
use iron::middleware::{AroundMiddleware,Handler};
use iron::typemap;

pub mod backends;
pub mod errors;

/// Re-export of the cookie crate
pub mod cookie {
    pub use _cookie::*;
}

/// A simple key-value storage interface that is internally used by `Session`. After request
/// handling the `write` method is called where the session backend has the chance to e.g. set
/// cookies or otherwise modify the response.
pub trait RawSession {
    fn get_raw(&self, key: &str) -> IronResult<Option<String>>;
    fn set_raw(&mut self, key: &str, value: String) -> IronResult<()>;
    fn clear(&mut self) -> IronResult<()>;
    fn write(&self, response: &mut Response) -> IronResult<()>;
}

pub trait SessionBackend: Send + Sync + 'static {
    type S: RawSession;

    /// Parse the session before request handling and return the data in parsed form.
    fn from_request(&self, request: &mut Request) -> Self::S;
}

/// The most important type, the middleware you need to register.
///
/// First parameter is a session backend, which determines how your session data is actually
/// stored. Depending on whether you store your data clientside (signed cookies) or serverside
/// (e.g. Redis and a session key) you're going to have different security properties.
pub struct SessionStorage<B: SessionBackend> {
    backend: B
}

impl<B: SessionBackend> SessionStorage<B> {
    pub fn new(backend: B) -> Self {
        SessionStorage {
            backend: backend
        }
    }
}

/// The high-level interface you use to modify session data. You obtain this object with
/// `request.session()`.
pub struct Session {
    inner: Box<RawSession>,
    has_changed: bool,
}

impl Session {
    fn new(s: Box<RawSession>) -> Self {
        Session {
            inner: s,
            has_changed: false
        }
    }
}

/// A typed interface to the string-to-string mapping. Each type represents a key, each instance of
/// a type can be serialized into a value.
pub trait Value: Sized + 'static {
    fn get_key() -> &'static str;
    fn into_raw(self) -> String;
    fn from_raw(value: String) -> Option<Self>;
}

impl Session {
    /// Get a `Value` from the session.
    pub fn get<T: Value + Sized + 'static>(&self) -> IronResult<Option<T>> {
        Ok(try!(self.inner.get_raw(T::get_key())).and_then(T::from_raw))
    }

    /// Set a `Value` in the session.
    pub fn set<T: Value>(&mut self, t: T) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.set_raw(T::get_key(), t.into_raw())
    }

    /// Clear/delete the session
    pub fn clear(&mut self) -> IronResult<()> {
        // FIXME: Equality check for less unnecessary writes
        self.has_changed = true;
        self.inner.clear()
    }
}

struct SessionKey;
impl typemap::Key for SessionKey { type Value = Session; }

impl<B: SessionBackend> AroundMiddleware for SessionStorage<B> {
    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(move |req: &mut Request| -> IronResult<Response> {
            let s = self.backend.from_request(req);
            req.extensions.insert::<SessionKey>(Session::new(Box::new(s)));
            let mut res = handler.handle(req);
            let s = req.extensions.remove::<SessionKey>().unwrap();
            if s.has_changed {
                match res {
                    Ok(ref mut r) => try!(s.inner.write(r)),
                    Err(ref mut e) => try!(s.inner.write(&mut e.response))
                }
            };
            res
        })
    }
}

/// The helper trait to obtain your session data from a request.
pub trait SessionRequestExt {
    fn session(&mut self) -> &mut Session;
}

impl<'a, 'b> SessionRequestExt for Request<'a, 'b> {
    fn session(&mut self) -> &mut Session {
        self.extensions.get_mut::<SessionKey>().unwrap()
    }
}

fn get_default_cookie(key: String, value: String) -> cookie::Cookie {
    let mut rv = cookie::Cookie::new(key, value);
    rv.httponly = true;
    rv.path = Some("/".to_owned());
    rv
}

/// A module with some important traits to star-import.
pub mod traits {
    pub use super::{SessionRequestExt};
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>#![crate_type = "dylib"]
#![feature(plugin_registrar)]

#[macro_use]
extern crate log;
extern crate walkdir;

#[cfg(debug_assertions)]
fn generate_assets(parent_path: String) -> Box<Fn(String) -> Option<Vec<u8>>> {
    use std::fs::File;
    use std::path::Path;
    use std::io::Read;
    info!("rust-embed: loading folder -> {}", parent_path);
    Box::new(move |file_path| {
        let name = &format!("{}{}", parent_path, file_path);
        let path = &Path::new(name);
        let key = String::from(path.to_str().expect("Path does not have a string representation"));
        info!("rust-embed: asset from file -> {}", key);
        let mut file = match File::open(path) {
            Ok(mut file) => file,
            Err(e) => {
                error!("rust-embed: could not open file -> {} {}", key, e);
                return None
            }
        };
        let mut data: Vec<u8> = Vec::new();
        match file.read_to_end(&mut data) {
            Ok(_) => Some(data),
            Err(e) =>  {
                error!("rust-embed: could not open file -> {} {}", key, e);
                return None
            }
        }
    })
}

#[cfg(not(debug_assertions))]
fn generate_assets<'a>(parent_path: String) -> Box<Fn(String) -> Option<Vec<u8>>> {
    use std::fs::File;
    use std::io::Read;
    use std::path::Path;
    use walkdir::WalkDir;
    use std::collections::HashMap;

    info!("rust-embed: loading folder -> {}", parent_path);
    let mut map = HashMap::new();
    for entry in WalkDir::new(parent_path.clone()).into_iter().filter_map(|e| e.ok()).filter(|e| e.file_type().is_file()) {
        info!("rust-embed: asset from file -> {}", entry.path().display());
        let base = &parent_path.clone();
        let key = String::from(entry.path().to_str().expect("Path does not have a string representation")).replace(base, "");
        let mut file = File::open(&Path::new(&entry.path())).unwrap_or_else(|e| {
            panic!("rust-embed: could not open file -> {} {}", key, e);
        });
        let mut data: Vec<u8> = Vec::new();
        file.read_to_end(&mut data).unwrap_or_else(|e| {
            panic!("rust-embed: could not read file -> {} {}", key, e);
        });
        map.insert(key, data);
    }
    Box::new(move |file_path| {
        match map.get(&file_path) {
            Some(s) => Some(s.to_vec()),
            None => None,
        }
    })
}

#[macro_export]
macro_rules! embed {
    ($x:expr) => ( ::generate_assets($x) )
}

macro_rules! register_macros {
    ($reg:expr, $($n:expr => $f:ident),+) => (
        $($reg.register_macro($n, macros::$f);)+
    )
}

/// Compiler hook for Rust to register plugins.
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    register_macros!(reg,
        "embed" => embed
    );
}

#[cfg(test)]
mod tests {
    #[test]
    #[cfg(debug_assertions)]
    fn dev() {
        let asset = embed!("examples/public".to_owned());
        match asset("/index.html".to_owned()) {
            None => assert!(false, "index.html should exist"),
            _ => assert!(true),
        }
        match asset("/gg.html".to_owned()) {
            Some(_) => assert!(false, "gg.html should not exist"),
            _ => assert!(true),
        }
        match asset("/images/llama.png".to_owned()) {
            None => assert!(false, "llama.png should exist"),
            _ => assert!(true),
        }
    }

    #[test]
    #[cfg(not(debug_assertions))]
    fn prod() {
        let asset = embed!("examples/public".to_owned());
        match asset("/index.html".to_owned()) {
            None => assert!(false, "index.html should exist"),
            _ => assert!(true),
        }
        match asset("/gg.html".to_owned()) {
            Some(_) => assert!(false, "gg.html should not exist"),
            _ => assert!(true),
        }
        match asset("/images/llama.png".to_owned()) {
            None => assert!(false, "llama.png should exist"),
            _ => assert!(true),
        }
    }
}
<commit_msg>fix registry problem<commit_after>#[macro_use]
extern crate log;
extern crate walkdir;

#[cfg(debug_assertions)]
fn generate_assets(parent_path: String) -> Box<Fn(String) -> Option<Vec<u8>>> {
    use std::fs::File;
    use std::path::Path;
    use std::io::Read;
    info!("rust-embed: loading folder -> {}", parent_path);
    Box::new(move |file_path| {
        let name = &format!("{}{}", parent_path, file_path);
        let path = &Path::new(name);
        let key = String::from(path.to_str().expect("Path does not have a string representation"));
        info!("rust-embed: asset from file -> {}", key);
        let mut file = match File::open(path) {
            Ok(mut file) => file,
            Err(e) => {
                error!("rust-embed: could not open file -> {} {}", key, e);
                return None
            }
        };
        let mut data: Vec<u8> = Vec::new();
        match file.read_to_end(&mut data) {
            Ok(_) => Some(data),
            Err(e) =>  {
                error!("rust-embed: could not open file -> {} {}", key, e);
                return None
            }
        }
    })
}

#[cfg(not(debug_assertions))]
fn generate_assets<'a>(parent_path: String) -> Box<Fn(String) -> Option<Vec<u8>>> {
    use std::fs::File;
    use std::io::Read;
    use std::path::Path;
    use walkdir::WalkDir;
    use std::collections::HashMap;

    info!("rust-embed: loading folder -> {}", parent_path);
    let mut map = HashMap::new();
    for entry in WalkDir::new(parent_path.clone()).into_iter().filter_map(|e| e.ok()).filter(|e| e.file_type().is_file()) {
        info!("rust-embed: asset from file -> {}", entry.path().display());
        let base = &parent_path.clone();
        let key = String::from(entry.path().to_str().expect("Path does not have a string representation")).replace(base, "");
        let mut file = File::open(&Path::new(&entry.path())).unwrap_or_else(|e| {
            panic!("rust-embed: could not open file -> {} {}", key, e);
        });
        let mut data: Vec<u8> = Vec::new();
        file.read_to_end(&mut data).unwrap_or_else(|e| {
            panic!("rust-embed: could not read file -> {} {}", key, e);
        });
        map.insert(key, data);
    }
    Box::new(move |file_path| {
        match map.get(&file_path) {
            Some(s) => Some(s.to_vec()),
            None => None,
        }
    })
}

#[macro_export]
macro_rules! embed {
    ($x:expr) => ( ::generate_assets($x) )
}

#[cfg(test)]
mod tests {
    #[test]
    #[cfg(debug_assertions)]
    fn dev() {
        let asset = embed!("examples/public".to_owned());
        match asset("/index.html".to_owned()) {
            None => assert!(false, "index.html should exist"),
            _ => assert!(true),
        }
        match asset("/gg.html".to_owned()) {
            Some(_) => assert!(false, "gg.html should not exist"),
            _ => assert!(true),
        }
        match asset("/images/llama.png".to_owned()) {
            None => assert!(false, "llama.png should exist"),
            _ => assert!(true),
        }
    }

    #[test]
    #[cfg(not(debug_assertions))]
    fn prod() {
        let asset = embed!("examples/public".to_owned());
        match asset("/index.html".to_owned()) {
            None => assert!(false, "index.html should exist"),
            _ => assert!(true),
        }
        match asset("/gg.html".to_owned()) {
            Some(_) => assert!(false, "gg.html should not exist"),
            _ => assert!(true),
        }
        match asset("/images/llama.png".to_owned()) {
            None => assert!(false, "llama.png should exist"),
            _ => assert!(true),
        }
    }
}
<|endoftext|>


<commit_before>#![deny(warnings)]
#![deny(missing_docs)]

//! A logger configured via an environment variable which writes to standard
//! error with nice colored output for log levels.
//!
//! ## Example
//!
//! ```
//! extern crate pretty_env_logger;
//! #[macro_use] extern crate log;
//!
//! fn main() {
//!     pretty_env_logger::init();
//!
//!     trace!("a trace example");
//!     debug!("deboogging");
//!     info!("such information");
//!     warn!("o_O");
//!     error!("boom");
//! }
//! ```

extern crate ansi_term;
extern crate env_logger;
extern crate log;

use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

use ansi_term::{Color, Style};
use env_logger::Builder;
use log::Level;

struct ColorLevel(Level);

impl fmt::Display for ColorLevel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Level::Trace => Color::Purple.paint("TRACE"),
            Level::Debug => Color::Blue.paint("DEBUG"),
            Level::Info => Color::Green.paint("INFO "),
            Level::Warn => Color::Yellow.paint("WARN "),
            Level::Error => Color::Red.paint("ERROR")
        }.fmt(f)
    }
}

static MAX_MODULE_WIDTH: AtomicUsize = ATOMIC_USIZE_INIT;

/// Initializes the global logger with a pretty env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Panics
///
/// This function fails to set the global logger if one has already been set.
#[inline]
pub fn init() {
    try_init().unwrap();
}

/// Initializes the global logger with a pretty env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn try_init() -> Result<(), log::SetLoggerError> {
    try_init_custom_env("RUST_LOG")
}

/// Initialized the global logger with a pretty env logger, with a custom variable name.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Panics
///
/// This function fails to set the global logger if one has already been set.
pub fn init_custom_env(environment_variable_name: &str) {
    try_init_custom_env(environment_variable_name).unwrap();
}

/// Initialized the global logger with a pretty env logger, with a custom variable name.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn try_init_custom_env(environment_variable_name: &str) -> Result<(), log::SetLoggerError> {
    let mut builder = formatted_builder()?;

    if let Ok(s) = ::std::env::var(environment_variable_name) {
        builder.parse(&s);
    }

    builder.try_init()
}

/// Returns a `env_logger::Builder` for further customization.
///
/// This method will return a colored and formatted) `env_logger::Builder`
/// for further customization. Tefer to env_logger::Build crate documentation
/// for further details and usage.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn formatted_builder() -> Result<Builder, log::SetLoggerError> {
    let mut builder = Builder::new();

    builder.format(|f, record| {
        use std::io::Write;
        let target = record.target();
        let mut max_width = MAX_MODULE_WIDTH.load(Ordering::Relaxed);
        if max_width < target.len() {
            MAX_MODULE_WIDTH.store(target.len(), Ordering::Relaxed);
            max_width = target.len();
        }
        writeln!(f, " {} {} > {}",
                 ColorLevel(record.level()),
                 Style::new().bold().paint(format!("{: <width$}", target, width=max_width)),
                 record.args())
    });

    Ok(builder)
}
<commit_msg>Fix typo in formatted_builder docs<commit_after>#![deny(warnings)]
#![deny(missing_docs)]

//! A logger configured via an environment variable which writes to standard
//! error with nice colored output for log levels.
//!
//! ## Example
//!
//! ```
//! extern crate pretty_env_logger;
//! #[macro_use] extern crate log;
//!
//! fn main() {
//!     pretty_env_logger::init();
//!
//!     trace!("a trace example");
//!     debug!("deboogging");
//!     info!("such information");
//!     warn!("o_O");
//!     error!("boom");
//! }
//! ```

extern crate ansi_term;
extern crate env_logger;
extern crate log;

use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

use ansi_term::{Color, Style};
use env_logger::Builder;
use log::Level;

struct ColorLevel(Level);

impl fmt::Display for ColorLevel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            Level::Trace => Color::Purple.paint("TRACE"),
            Level::Debug => Color::Blue.paint("DEBUG"),
            Level::Info => Color::Green.paint("INFO "),
            Level::Warn => Color::Yellow.paint("WARN "),
            Level::Error => Color::Red.paint("ERROR")
        }.fmt(f)
    }
}

static MAX_MODULE_WIDTH: AtomicUsize = ATOMIC_USIZE_INIT;

/// Initializes the global logger with a pretty env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Panics
///
/// This function fails to set the global logger if one has already been set.
#[inline]
pub fn init() {
    try_init().unwrap();
}

/// Initializes the global logger with a pretty env logger.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn try_init() -> Result<(), log::SetLoggerError> {
    try_init_custom_env("RUST_LOG")
}

/// Initialized the global logger with a pretty env logger, with a custom variable name.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Panics
///
/// This function fails to set the global logger if one has already been set.
pub fn init_custom_env(environment_variable_name: &str) {
    try_init_custom_env(environment_variable_name).unwrap();
}

/// Initialized the global logger with a pretty env logger, with a custom variable name.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn try_init_custom_env(environment_variable_name: &str) -> Result<(), log::SetLoggerError> {
    let mut builder = formatted_builder()?;

    if let Ok(s) = ::std::env::var(environment_variable_name) {
        builder.parse(&s);
    }

    builder.try_init()
}

/// Returns a `env_logger::Builder` for further customization.
///
/// This method will return a colored and formatted) `env_logger::Builder`
/// for further customization. Refer to env_logger::Build crate documentation
/// for further details and usage.
///
/// This should be called early in the execution of a Rust program, and the
/// global logger may only be initialized once. Future initialization attempts
/// will return an error.
///
/// # Errors
///
/// This function fails to set the global logger if one has already been set.
pub fn formatted_builder() -> Result<Builder, log::SetLoggerError> {
    let mut builder = Builder::new();

    builder.format(|f, record| {
        use std::io::Write;
        let target = record.target();
        let mut max_width = MAX_MODULE_WIDTH.load(Ordering::Relaxed);
        if max_width < target.len() {
            MAX_MODULE_WIDTH.store(target.len(), Ordering::Relaxed);
            max_width = target.len();
        }
        writeln!(f, " {} {} > {}",
                 ColorLevel(record.level()),
                 Style::new().bold().paint(format!("{: <width$}", target, width=max_width)),
                 record.args())
    });

    Ok(builder)
}
<|endoftext|>


<commit_before>extern crate libc;
use std::ffi::CString;

#[allow(dead_code,
        non_snake_case,
        non_camel_case_types,
        non_upper_case_globals)]
pub mod libpq;

// Implementation of initialization and callbacks.

pub unsafe extern fn init(cb: *mut libpq::OutputPluginCallbacks) {
    (*cb).startup_cb = Some(startup);
    (*cb).begin_cb = Some(begin);
    (*cb).change_cb = Some(change);
    (*cb).commit_cb = Some(commit);
    (*cb).shutdown_cb = Some(shutdown);
}

#[allow(unused_variables)]
extern fn startup(ctx: *mut libpq::Struct_LogicalDecodingContext,
                  options: *mut libpq::OutputPluginOptions,
                  is_init: libpq::_bool) {
    unsafe {
        (*options).output_type = libpq::OUTPUT_PLUGIN_TEXTUAL_OUTPUT;
    }
}

#[allow(unused_variables)]
extern fn begin(ctx: *mut libpq::Struct_LogicalDecodingContext,
                txn: *mut libpq::ReorderBufferTXN) {
    unsafe {
        let is_last = 1;                                  // True in C language
        let s = CString::new("{ \"begin\": %u }").unwrap();
        libpq::OutputPluginPrepareWrite(ctx, is_last);
        libpq::appendStringInfo((*ctx).out, s.as_ptr(), (*txn).xid);
        libpq::OutputPluginWrite(ctx, is_last);
    }
}

#[allow(unused_variables)]
extern fn change(ctx: *mut libpq::Struct_LogicalDecodingContext,
                 txn: *mut libpq::ReorderBufferTXN,
                 relation: libpq::Relation,
                 change: *mut libpq::ReorderBufferChange) {
    unsafe {
        let last = 1;                                     // True in C language
        libpq::OutputPluginPrepareWrite(ctx, last);
        append_change(relation, change, (*ctx).out);
        libpq::OutputPluginWrite(ctx, last);
    }
}

#[allow(unused_variables)]
extern fn commit(ctx: *mut libpq::Struct_LogicalDecodingContext,
                 txn: *mut libpq::ReorderBufferTXN,
                 lsn: libpq::XLogRecPtr) {
    unsafe {
        let last = 1;                                     // True in C language
        let s = CString::new("{ \"commit\": %u }").unwrap();
        libpq::OutputPluginPrepareWrite(ctx, last);
        libpq::appendStringInfo((*ctx).out, s.as_ptr(), (*txn).xid);
        libpq::OutputPluginWrite(ctx, last);
    }
}

#[allow(unused_variables)]
extern fn shutdown(ctx: *mut libpq::Struct_LogicalDecodingContext) {
  // Do nothing.
}

unsafe fn append_change(relation: libpq::Relation,
                        change: *mut libpq::ReorderBufferChange,
                        out: libpq::StringInfo) {
    let tuple_desc = (*relation).rd_att;
    let tuples = (*change).data.tp();
    let tuple_new = (*tuples).newtuple;
    let tuple_old = (*tuples).oldtuple;
    let token = match (*change).action {
        libpq::REORDER_BUFFER_CHANGE_INSERT => "insert",
        libpq::REORDER_BUFFER_CHANGE_UPDATE => "update",
        libpq::REORDER_BUFFER_CHANGE_DELETE => "delete",
        _ => panic!("Unrecognized change action!")
    };
    append("{ ", out);
    append("\"", out);
    append(token, out);
    append("\": ", out);
    append_tuple_buf_as_json(tuple_new, tuple_desc, out);
    if !tuple_old.is_null() {
        append(", \"@\": ", out);
        append_tuple_buf_as_json(tuple_old, tuple_desc, out);
    }
    append(" }", out);
}

unsafe fn append_tuple_buf_as_json(data: *mut libpq::ReorderBufferTupleBuf,
                                   desc: libpq::TupleDesc,
                                   out: libpq::StringInfo) {
    if !data.is_null() {
        let heap_tuple = &mut (*data).tuple;
        let datum = libpq::heap_copy_tuple_as_datum(heap_tuple, desc);
        let empty_oid: libpq::Oid = 0;
        let json = libpq::DirectFunctionCall1Coll(Some(row_to_json),
                                                  empty_oid,
                                                  datum);
        let ptr = json as *const libpq::Struct_varlena;
        let text = libpq::text_to_cstring(ptr);
        libpq::appendStringInfoString(out, text);
    } else {
        append("{}", out);
    }
}

unsafe fn append<T: Into<Vec<u8>>>(t: T, out: libpq::StringInfo) {
    libpq::appendStringInfoString(out, CString::new(t).unwrap().as_ptr());
}

extern fn row_to_json(fcinfo: libpq::FunctionCallInfo) -> libpq::Datum {
    // We wrap the unsafe call to make it safe.
    unsafe {
        libpq::row_to_json(fcinfo)
    }
}

// Symbols Postgres needs to find.

#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern fn _PG_init() { }

#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern fn
    _PG_output_plugin_init(cb: *mut libpq::OutputPluginCallbacks) { init(cb); }
<commit_msg>Capture the transaction commit time<commit_after>extern crate libc;
use std::ffi::CString;

#[allow(dead_code,
        non_snake_case,
        non_camel_case_types,
        non_upper_case_globals)]
pub mod libpq;

// Implementation of initialization and callbacks.

pub unsafe extern fn init(cb: *mut libpq::OutputPluginCallbacks) {
    (*cb).startup_cb = Some(startup);
    (*cb).begin_cb = Some(begin);
    (*cb).change_cb = Some(change);
    (*cb).commit_cb = Some(commit);
    (*cb).shutdown_cb = Some(shutdown);
}

#[allow(unused_variables)]
extern fn startup(ctx: *mut libpq::Struct_LogicalDecodingContext,
                  options: *mut libpq::OutputPluginOptions,
                  is_init: libpq::_bool) {
    unsafe {
        (*options).output_type = libpq::OUTPUT_PLUGIN_TEXTUAL_OUTPUT;
    }
}

#[allow(unused_variables)]
extern fn begin(ctx: *mut libpq::Struct_LogicalDecodingContext,
                txn: *mut libpq::ReorderBufferTXN) {
    unsafe {
        let is_last = 1;                                  // True in C language
        let s = CString::new("{ \"begin\": %u }").unwrap();
        libpq::OutputPluginPrepareWrite(ctx, is_last);
        libpq::appendStringInfo((*ctx).out, s.as_ptr(), (*txn).xid);
        libpq::OutputPluginWrite(ctx, is_last);
    }
}

#[allow(unused_variables)]
extern fn change(ctx: *mut libpq::Struct_LogicalDecodingContext,
                 txn: *mut libpq::ReorderBufferTXN,
                 relation: libpq::Relation,
                 change: *mut libpq::ReorderBufferChange) {
    unsafe {
        let last = 1;                                     // True in C language
        libpq::OutputPluginPrepareWrite(ctx, last);
        append_change(relation, change, (*ctx).out);
        libpq::OutputPluginWrite(ctx, last);
    }
}

#[allow(unused_variables)]
extern fn commit(ctx: *mut libpq::Struct_LogicalDecodingContext,
                 txn: *mut libpq::ReorderBufferTXN,
                 lsn: libpq::XLogRecPtr) {
    unsafe {
        let last = 1;                                     // True in C language
        let s = CString::new("{ \"commit\": %u, \"t\": \"%s\" }").unwrap();
        let t = libpq::timestamptz_to_str((*txn).commit_time);
        libpq::OutputPluginPrepareWrite(ctx, last);
        libpq::appendStringInfo((*ctx).out, s.as_ptr(), (*txn).xid, t);
        libpq::OutputPluginWrite(ctx, last);
    }
}

#[allow(unused_variables)]
extern fn shutdown(ctx: *mut libpq::Struct_LogicalDecodingContext) {
  // Do nothing.
}

unsafe fn append_change(relation: libpq::Relation,
                        change: *mut libpq::ReorderBufferChange,
                        out: libpq::StringInfo) {
    let tuple_desc = (*relation).rd_att;
    let tuples = (*change).data.tp();
    let tuple_new = (*tuples).newtuple;
    let tuple_old = (*tuples).oldtuple;
    let token = match (*change).action {
        libpq::REORDER_BUFFER_CHANGE_INSERT => "insert",
        libpq::REORDER_BUFFER_CHANGE_UPDATE => "update",
        libpq::REORDER_BUFFER_CHANGE_DELETE => "delete",
        _ => panic!("Unrecognized change action!")
    };
    append("{ ", out);
    append("\"", out);
    append(token, out);
    append("\": ", out);
    append_tuple_buf_as_json(tuple_new, tuple_desc, out);
    if !tuple_old.is_null() {
        append(", \"@\": ", out);
        append_tuple_buf_as_json(tuple_old, tuple_desc, out);
    }
    append(" }", out);
}

unsafe fn append_tuple_buf_as_json(data: *mut libpq::ReorderBufferTupleBuf,
                                   desc: libpq::TupleDesc,
                                   out: libpq::StringInfo) {
    if !data.is_null() {
        let heap_tuple = &mut (*data).tuple;
        let datum = libpq::heap_copy_tuple_as_datum(heap_tuple, desc);
        let empty_oid: libpq::Oid = 0;
        let json = libpq::DirectFunctionCall1Coll(Some(row_to_json),
                                                  empty_oid,
                                                  datum);
        let ptr = json as *const libpq::Struct_varlena;
        let text = libpq::text_to_cstring(ptr);
        libpq::appendStringInfoString(out, text);
    } else {
        append("{}", out);
    }
}

unsafe fn append<T: Into<Vec<u8>>>(t: T, out: libpq::StringInfo) {
    libpq::appendStringInfoString(out, CString::new(t).unwrap().as_ptr());
}

extern fn row_to_json(fcinfo: libpq::FunctionCallInfo) -> libpq::Datum {
    // We wrap the unsafe call to make it safe.
    unsafe {
        libpq::row_to_json(fcinfo)
    }
}

// Symbols Postgres needs to find.

#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern fn _PG_init() { }

#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern fn
    _PG_output_plugin_init(cb: *mut libpq::OutputPluginCallbacks) { init(cb); }
<|endoftext|>