<commit_before>#![feature(libc)]
extern crate libc;

use std::mem;
use self::libc::{c_int, c_uint, c_ushort, c_uchar, STDOUT_FILENO};
use self::libc::ioctl;

use std::io::{Write, Result as IoResult};

extern {
    static tiocgwinsz: c_int;

    fn tcgetattr(filedes: c_int, termptr: *mut Termios) -> c_int;
    fn tcsetattr(filedes: c_int, opt: c_int, termptr: *mut Termios) -> c_int;
    fn cfmakeraw(termptr: *mut Termios);
}

#[repr(C)]
struct TermSize {
    row: c_ushort,
    col: c_ushort,
    _x: c_ushort,
    _y: c_ushort,
}

/// Get the size of the terminal. If the program isn't running in a terminal, it will return
/// `None`.
pub fn termsize() -> Option<(usize, usize)> {
    unsafe {
        let mut size: TermSize = mem::zeroed();

        if ioctl(STDOUT_FILENO, tiocgwinsz as u64, &mut size as *mut _) == 0 {
            Some((size.col as usize, size.row as usize))
        } else {
            None
        }
    }
}

#[derive(Clone)]
#[repr(C)]
struct Termios {
    c_iflag: c_uint,
    c_oflag: c_uint,
    c_cflag: c_uint,
    c_lflag: c_uint,
    c_line: c_uchar,
    c_cc: [c_uchar; 32],
    c_ispeed: c_uint,
    c_ospeed: c_uint,
}

fn get_terminal_attr() -> (Termios, c_int) {
    unsafe {
        let mut ios = Termios {
            c_iflag: 0,
            c_oflag: 0,
            c_cflag: 0,
            c_lflag: 0,
            c_line: 0,
            c_cc: [0; 32],
            c_ispeed: 0,
            c_ospeed: 0
        };

        let attr = tcgetattr(0, &mut ios);
        (ios, attr)
    }
}

fn make_raw(ios: &mut Termios) {
    unsafe {
        cfmakeraw(&mut *ios);
    }
}

fn set_terminal_attr(ios: *mut Termios) -> c_int {
    unsafe {
        tcsetattr(0, 0, ios)
    }
}

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
pub struct TerminalRestorer {
    prev_ios: Termios
}

impl Drop for TerminalRestorer {
    fn drop(&mut self) {
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

/// Switch to raw mode.
///
/// Raw mode means that stdin won't be printed (it will instead have to be written manually by the
/// program). Furthermore, the input isn't canonicalised or buffered (that is, you can read from
/// stdin one byte of a time). The output is neither modified in any way.
///
/// Panics
/// ------
///
/// This may panic if the Termios settings can be set or loaded properly.
pub fn raw_mode() -> TerminalRestorer {
    let (mut ios, err) = get_terminal_attr();
    let prev_ios = ios.clone();
    if err != 0 {
        panic!("Failed to load termios settings properly.");
    }

    make_raw(&mut ios);

    if set_terminal_attr(&mut ios as *mut _) != 0 {
        panic!("Failed to init termios raw mode properly.");
    }

    TerminalRestorer {
        prev_ios: prev_ios,
    }
}

/// Controlling terminals.
pub trait TermControl {
    /// Print the CSI (control sequence introducer) followed by a byte string.
    fn csi(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Clear the terminal.
    fn clear(&mut self) -> IoResult<usize> {
        self.csi(b"2J")
    }
    /// Show the cursor.
    fn show(&mut self) -> IoResult<usize> {
        self.csi(b"?25h")
    }
    /// Hide the cursor.
    fn hide(&mut self) -> IoResult<usize> {
        self.csi(b"?25l")
    }
    /// Reset the style of the cursor.
    fn reset_style(&mut self) -> IoResult<usize> {
        self.csi(b"0m")
    }
    /// Go to a given position.
    fn goto(&mut self, x: usize, y: usize) -> IoResult<usize> {
        self.csi(format!("{};{}H", x, y).as_bytes())
    }
}

impl<W: Write> TermControl for W {
    fn csi(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b[").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
}
<commit_msg>u16 instead, don't allocate for formatting<commit_after>#![feature(libc)]
extern crate libc;

use std::mem;
use self::libc::{c_int, c_uint, c_ushort, c_uchar, STDOUT_FILENO};
use self::libc::ioctl;

use std::io::{Write, Result as IoResult};

extern {
    static tiocgwinsz: c_int;

    fn tcgetattr(filedes: c_int, termptr: *mut Termios) -> c_int;
    fn tcsetattr(filedes: c_int, opt: c_int, termptr: *mut Termios) -> c_int;
    fn cfmakeraw(termptr: *mut Termios);
}

#[repr(C)]
struct TermSize {
    row: c_ushort,
    col: c_ushort,
    _x: c_ushort,
    _y: c_ushort,
}

/// Get the size of the terminal. If the program isn't running in a terminal, it will return
/// `None`.
pub fn termsize() -> Option<(usize, usize)> {
    unsafe {
        let mut size: TermSize = mem::zeroed();

        if ioctl(STDOUT_FILENO, tiocgwinsz as u64, &mut size as *mut _) == 0 {
            Some((size.col as usize, size.row as usize))
        } else {
            None
        }
    }
}

#[derive(Clone)]
#[repr(C)]
struct Termios {
    c_iflag: c_uint,
    c_oflag: c_uint,
    c_cflag: c_uint,
    c_lflag: c_uint,
    c_line: c_uchar,
    c_cc: [c_uchar; 32],
    c_ispeed: c_uint,
    c_ospeed: c_uint,
}

fn get_terminal_attr() -> (Termios, c_int) {
    unsafe {
        let mut ios = Termios {
            c_iflag: 0,
            c_oflag: 0,
            c_cflag: 0,
            c_lflag: 0,
            c_line: 0,
            c_cc: [0; 32],
            c_ispeed: 0,
            c_ospeed: 0
        };

        let attr = tcgetattr(0, &mut ios);
        (ios, attr)
    }
}

fn make_raw(ios: &mut Termios) {
    unsafe {
        cfmakeraw(&mut *ios);
    }
}

fn set_terminal_attr(ios: *mut Termios) -> c_int {
    unsafe {
        tcsetattr(0, 0, ios)
    }
}

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
pub struct TerminalRestorer {
    prev_ios: Termios
}

impl Drop for TerminalRestorer {
    fn drop(&mut self) {
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

/// Switch to raw mode.
///
/// Raw mode means that stdin won't be printed (it will instead have to be written manually by the
/// program). Furthermore, the input isn't canonicalised or buffered (that is, you can read from
/// stdin one byte of a time). The output is neither modified in any way.
///
/// Panics
/// ------
///
/// This may panic if the Termios settings can be set or loaded properly.
pub fn raw_mode() -> TerminalRestorer {
    let (mut ios, err) = get_terminal_attr();
    let prev_ios = ios.clone();
    if err != 0 {
        panic!("Failed to load termios settings properly.");
    }

    make_raw(&mut ios);

    if set_terminal_attr(&mut ios as *mut _) != 0 {
        panic!("Failed to init termios raw mode properly.");
    }

    TerminalRestorer {
        prev_ios: prev_ios,
    }
}

/// Controlling terminals.
pub trait TermControl {
    /// Print the CSI (control sequence introducer) followed by a byte string.
    fn csi(&mut self, b: &[u8]) -> IoResult<usize>;
    /// Clear the terminal.
    fn clear(&mut self) -> IoResult<usize> {
        self.csi(b"2J")
    }
    /// Show the cursor.
    fn show(&mut self) -> IoResult<usize> {
        self.csi(b"?25h")
    }
    /// Hide the cursor.
    fn hide(&mut self) -> IoResult<usize> {
        self.csi(b"?25l")
    }
    /// Reset the style of the cursor.
    fn reset_style(&mut self) -> IoResult<usize> {
        self.csi(b"0m")
    }
    /// Go to a given position.
    fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
        self.csi(&[
             (x / 10000 % 10) as u8, (x / 1000 % 10) as u8, (x / 100 % 10) as u8, (x / 10 % 10) as u8, (x % 10) as u8,
             b';',
             (y / 10000 % 10) as u8, (y / 1000 % 10) as u8, (y / 100 % 10) as u8, (y / 10 % 10) as u8, (y % 10) as u8,
             b'H',
        ])
    }
}

impl<W: Write> TermControl for W {
    fn csi(&mut self, b: &[u8]) -> IoResult<usize> {
        self.write(b"\x1b[").and_then(|x| {
            self.write(b).map(|y| x + y)
        })
    }
}
<|endoftext|>


<commit_before>extern crate libc;
/*
 * seccomp actions
 */
#[allow(non_camel_case_types)]
pub type scmp_filter_ctx = libc::c_void;

/**
 * Kill the process
 */
pub const SCMP_ACT_KILL: u32  = 0x00000000;
/**
 * Throw a SIGSYS signal
 */
pub const SCMP_ACT_TRAP: u32 = 0x00030000;
/**
 * Return the specified error code
 */
#[allow(non_snake_case)]
pub fn SCMP_ACT_ERRNO(x: u32) -> u32 { 0x00050000 | ((x) & 0x0000ffff) }
/**
 * Notify a tracing process with the specified value
 */
#[allow(non_snake_case)]
pub fn SCMP_ACT_TRACE(x: u32) -> u32 { 0x7ff00000 | ((x) & 0x0000ffff) }
/**
 * Allow the syscall to be executed
 */
pub const SCMP_ACT_ALLOW: u32 = 0x7fff0000;

/**
 * Filter attributes
 */
#[repr(C)]
pub enum scmp_filter_attr {
    _SCMP_FLTATR_MIN,
    SCMP_FLTATR_ACT_DEFAULT, /**< default filter action */
    SCMP_FLTATR_ACT_BADARCH, /**< bad architecture action */
    SCMP_FLTATR_CTL_NNP, /**< set NO_NEW_PRIVS on filter load */
    _SCMP_FLTATR_MAX,
}

/**
 * Comparison operators
 */
#[repr(C)]
pub enum scmp_compare {
        _SCMP_CMP_MIN = 0,
        SCMP_CMP_NE = 1,                /**< not equal */
        SCMP_CMP_LT = 2,                /**< less than */
        SCMP_CMP_LE = 3,                /**< less than or equal */
        SCMP_CMP_EQ = 4,                /**< equal */
        SCMP_CMP_GE = 5,                /**< greater than or equal */
        SCMP_CMP_GT = 6,                /**< greater than */
        SCMP_CMP_MASKED_EQ = 7,         /**< masked equality */
        _SCMP_CMP_MAX,
}

/**
 * Argument datum
 */
#[allow(non_camel_case_types)]
pub type scmp_datum_t = libc::uint64_t;

/**
 * Argument / Value comparison definition
 */
#[repr(C)]
pub struct scmp_arg_cmp {
        pub arg: libc::c_uint,        /**< argument number, starting at 0 */
        pub op: scmp_compare,       /**< the comparison op, e.g. SCMP_CMP_* */
        pub datum_a: scmp_datum_t,
        pub datum_b: scmp_datum_t,
}

#[link(name = "seccomp")]
extern {
    /**
     * Initialize the filter state
     *
     * @param def_action the default filter action
     *
     * This function initializes the internal seccomp filter state and should
     * be called before any other functions in this library to ensure the filter
     * state is initialized.  Returns a filter context on success, NULL on failure.
     *
     */
    pub fn seccomp_init(def_action: libc::uint32_t) -> *mut scmp_filter_ctx;
    /**
     * Reset the filter state
     *
     * @param ctx the filter context
     * @param def_action the default filter action
     *
     * This function resets the given seccomp filter state and ensures the
     * filter state is reinitialized.  This function does not reset any seccomp
     * filters already loaded into the kernel.  Returns zero on success, negative
     * values on failure.
     *
     */
    pub fn seccomp_reset(ctx: *mut scmp_filter_ctx, def_action: libc::uint32_t) -> libc::c_int;
    /**
     * Destroys the filter state and releases any resources
     *
     * @param ctx the filter context
     *
     * This functions destroys the given seccomp filter state and releases any
     * resources, including memory, associated with the filter state.  This
     * function does not reset any seccomp filters already loaded into the kernel.
     * The filter context can no longer be used after calling this function.
     *
     */
    pub fn seccomp_release(ctx: *mut scmp_filter_ctx);
    /**
     * Loads the filter into the kernel
     *
     * @param ctx the filter context
     *
     * This function loads the given seccomp filter context into the kernel.  If
     * the filter was loaded correctly, the kernel will be enforcing the filter
     * when this function returns.  Returns zero on success, negative values on
     * error.
     *
     */
    pub fn seccomp_load(ctx: *const scmp_filter_ctx) -> libc::c_int;

    /**
     * Get the value of a filter attribute
     *
     * @param ctx the filter context
     * @param attr the filter attribute name
     * @param value the filter attribute value
     *
     * This function fetches the value of the given attribute name and returns it
     * via @value.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_attr_get(ctx: *const scmp_filter_ctx,
                         attr: scmp_filter_attr, value: *mut libc::uint32_t) -> libc::c_int;

    /**
     * Set the value of a filter attribute
     *
     * @param ctx the filter context
     * @param attr the filter attribute name
     * @param value the filter attribute value
     *
     * This function sets the value of the given attribute.  Returns zero on
     * success, negative values on failure.
     *
     */
    pub fn seccomp_attr_set(ctx: *mut scmp_filter_ctx,
                         attr: scmp_filter_attr, value: libc::uint32_t) -> libc::c_int;

    /**
     * Set the priority of a given syscall
     *
     * @param ctx the filter context
     * @param syscall the syscall number
     * @param priority priority value, higher value == higher priority
     *
     * This function sets the priority of the given syscall; this value is used
     * when generating the seccomp filter code such that higher priority syscalls
     * will incur less filter code overhead than the lower priority syscalls in the
     * filter.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_syscall_priority(ctx: *mut scmp_filter_ctx,
                                 syscall: libc::c_int, priority: libc::uint8_t) -> libc::c_int;

    /**
     * Add a new rule to the filter
     *
     * @param ctx the filter context
     * @param action the filter action
     * @param syscall the syscall number
     * @param arg_cnt the number of argument filters in the argument filter chain
     * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended)
     *
     * This function adds a series of new argument/value checks to the seccomp
     * filter for the given syscall; multiple argument/value checks can be
     * specified and they will be chained together (AND'd together) in the filter.
     * If the specified rule needs to be adjusted due to architecture specifics it
     * will be adjusted without notification.  Returns zero on success, negative
     * values on failure.
     *
     */
    pub fn seccomp_rule_add(ctx: *mut scmp_filter_ctx,
                         action: libc::uint32_t, syscall: libc::c_int, arg_cnt: libc::c_uint, ...) -> libc::c_int;

    /**
     * Add a new rule to the filter
     *
     * @param ctx the filter context
     * @param action the filter action
     * @param syscall the syscall number
     * @param arg_cnt the number of argument filters in the argument filter chain
     * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended)
     *
     * This function adds a series of new argument/value checks to the seccomp
     * filter for the given syscall; multiple argument/value checks can be
     * specified and they will be chained together (AND'd together) in the filter.
     * If the specified rule can not be represented on the architecture the
     * function will fail.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_rule_add_exact(ctx: *mut scmp_filter_ctx, action: libc::uint32_t,
                               syscall: libc::c_int, arg_cnt: libc::c_uint, ...) -> libc::c_int;

    /**
     * Generate seccomp Pseudo Filter Code (PFC) and export it to a file
     *
     * @param ctx the filter context
     * @param fd the destination fd
     *
     * This function generates seccomp Pseudo Filter Code (PFC) and writes it to
     * the given fd.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_export_pfc(ctx: *const scmp_filter_ctx, fd: libc::c_int) -> libc::c_int;

    /**
     * Generate seccomp Berkley Packet Filter (BPF) code and export it to a file
     *
     * @param ctx the filter context
     * @param fd the destination fd
     *
     * This function generates seccomp Berkley Packer Filter (BPF) code and writes
     * it to the given fd.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_export_bpf(ctx: *const scmp_filter_ctx, fd: libc::c_int) -> libc::c_int;
}

#[test]
fn does_it_even_work() {
    unsafe {
        let context = seccomp_init(SCMP_ACT_ALLOW);
        let comparator = scmp_arg_cmp {
            arg: 0,
            op: scmp_compare::SCMP_CMP_EQ,
            datum_a: 1000,
            datum_b: 0,
        };
        assert!(seccomp_rule_add(context, SCMP_ACT_KILL, 105, 1, comparator) == 0);
        assert!(seccomp_load(context) == 0);
        //assert!(libc::setuid(1000) == 0);
    }
}
<commit_msg>Fix comments<commit_after>extern crate libc;
/*
 * seccomp actions
 */
#[allow(non_camel_case_types)]
pub type scmp_filter_ctx = libc::c_void;

/**
 * Kill the process
 */
pub const SCMP_ACT_KILL: u32  = 0x00000000;
/**
 * Throw a SIGSYS signal
 */
pub const SCMP_ACT_TRAP: u32 = 0x00030000;
/**
 * Return the specified error code
 */
#[allow(non_snake_case)]
pub fn SCMP_ACT_ERRNO(x: u32) -> u32 { 0x00050000 | ((x) & 0x0000ffff) }
/**
 * Notify a tracing process with the specified value
 */
#[allow(non_snake_case)]
pub fn SCMP_ACT_TRACE(x: u32) -> u32 { 0x7ff00000 | ((x) & 0x0000ffff) }
/**
 * Allow the syscall to be executed
 */
pub const SCMP_ACT_ALLOW: u32 = 0x7fff0000;

/**
 * Filter attributes
 */
#[repr(C)]
pub enum scmp_filter_attr {
    _SCMP_FLTATR_MIN,
    SCMP_FLTATR_ACT_DEFAULT, /** default filter action */
    SCMP_FLTATR_ACT_BADARCH, /** bad architecture action */
    SCMP_FLTATR_CTL_NNP, /** set NO_NEW_PRIVS on filter load */
    _SCMP_FLTATR_MAX,
}

/**
 * Comparison operators
 */
#[repr(C)]
pub enum scmp_compare {
        _SCMP_CMP_MIN = 0,
        SCMP_CMP_NE = 1,                /** not equal */
        SCMP_CMP_LT = 2,                /** less than */
        SCMP_CMP_LE = 3,                /** less than or equal */
        SCMP_CMP_EQ = 4,                /** equal */
        SCMP_CMP_GE = 5,                /** greater than or equal */
        SCMP_CMP_GT = 6,                /** greater than */
        SCMP_CMP_MASKED_EQ = 7,         /** masked equality */
        _SCMP_CMP_MAX,
}

/**
 * Argument datum
 */
#[allow(non_camel_case_types)]
pub type scmp_datum_t = libc::uint64_t;

/**
 * Argument / Value comparison definition
 */
#[repr(C)]
pub struct scmp_arg_cmp {
        pub arg: libc::c_uint,        /** argument number, starting at 0 */
        pub op: scmp_compare,       /** the comparison op, e.g. SCMP_CMP_* */
        pub datum_a: scmp_datum_t,
        pub datum_b: scmp_datum_t,
}

#[link(name = "seccomp")]
extern {
    /**
     * Initialize the filter state
     *
     * @param def_action the default filter action
     *
     * This function initializes the internal seccomp filter state and should
     * be called before any other functions in this library to ensure the filter
     * state is initialized.  Returns a filter context on success, NULL on failure.
     *
     */
    pub fn seccomp_init(def_action: libc::uint32_t) -> *mut scmp_filter_ctx;
    /**
     * Reset the filter state
     *
     * @param ctx the filter context
     * @param def_action the default filter action
     *
     * This function resets the given seccomp filter state and ensures the
     * filter state is reinitialized.  This function does not reset any seccomp
     * filters already loaded into the kernel.  Returns zero on success, negative
     * values on failure.
     *
     */
    pub fn seccomp_reset(ctx: *mut scmp_filter_ctx, def_action: libc::uint32_t) -> libc::c_int;
    /**
     * Destroys the filter state and releases any resources
     *
     * @param ctx the filter context
     *
     * This functions destroys the given seccomp filter state and releases any
     * resources, including memory, associated with the filter state.  This
     * function does not reset any seccomp filters already loaded into the kernel.
     * The filter context can no longer be used after calling this function.
     *
     */
    pub fn seccomp_release(ctx: *mut scmp_filter_ctx);
    /**
     * Loads the filter into the kernel
     *
     * @param ctx the filter context
     *
     * This function loads the given seccomp filter context into the kernel.  If
     * the filter was loaded correctly, the kernel will be enforcing the filter
     * when this function returns.  Returns zero on success, negative values on
     * error.
     *
     */
    pub fn seccomp_load(ctx: *const scmp_filter_ctx) -> libc::c_int;

    /**
     * Get the value of a filter attribute
     *
     * @param ctx the filter context
     * @param attr the filter attribute name
     * @param value the filter attribute value
     *
     * This function fetches the value of the given attribute name and returns it
     * via @value.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_attr_get(ctx: *const scmp_filter_ctx,
                         attr: scmp_filter_attr, value: *mut libc::uint32_t) -> libc::c_int;

    /**
     * Set the value of a filter attribute
     *
     * @param ctx the filter context
     * @param attr the filter attribute name
     * @param value the filter attribute value
     *
     * This function sets the value of the given attribute.  Returns zero on
     * success, negative values on failure.
     *
     */
    pub fn seccomp_attr_set(ctx: *mut scmp_filter_ctx,
                         attr: scmp_filter_attr, value: libc::uint32_t) -> libc::c_int;

    /**
     * Set the priority of a given syscall
     *
     * @param ctx the filter context
     * @param syscall the syscall number
     * @param priority priority value, higher value == higher priority
     *
     * This function sets the priority of the given syscall; this value is used
     * when generating the seccomp filter code such that higher priority syscalls
     * will incur less filter code overhead than the lower priority syscalls in the
     * filter.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_syscall_priority(ctx: *mut scmp_filter_ctx,
                                 syscall: libc::c_int, priority: libc::uint8_t) -> libc::c_int;

    /**
     * Add a new rule to the filter
     *
     * @param ctx the filter context
     * @param action the filter action
     * @param syscall the syscall number
     * @param arg_cnt the number of argument filters in the argument filter chain
     * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended)
     *
     * This function adds a series of new argument/value checks to the seccomp
     * filter for the given syscall; multiple argument/value checks can be
     * specified and they will be chained together (AND'd together) in the filter.
     * If the specified rule needs to be adjusted due to architecture specifics it
     * will be adjusted without notification.  Returns zero on success, negative
     * values on failure.
     *
     */
    pub fn seccomp_rule_add(ctx: *mut scmp_filter_ctx,
                         action: libc::uint32_t, syscall: libc::c_int, arg_cnt: libc::c_uint, ...) -> libc::c_int;

    /**
     * Add a new rule to the filter
     *
     * @param ctx the filter context
     * @param action the filter action
     * @param syscall the syscall number
     * @param arg_cnt the number of argument filters in the argument filter chain
     * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended)
     *
     * This function adds a series of new argument/value checks to the seccomp
     * filter for the given syscall; multiple argument/value checks can be
     * specified and they will be chained together (AND'd together) in the filter.
     * If the specified rule can not be represented on the architecture the
     * function will fail.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_rule_add_exact(ctx: *mut scmp_filter_ctx, action: libc::uint32_t,
                               syscall: libc::c_int, arg_cnt: libc::c_uint, ...) -> libc::c_int;

    /**
     * Generate seccomp Pseudo Filter Code (PFC) and export it to a file
     *
     * @param ctx the filter context
     * @param fd the destination fd
     *
     * This function generates seccomp Pseudo Filter Code (PFC) and writes it to
     * the given fd.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_export_pfc(ctx: *const scmp_filter_ctx, fd: libc::c_int) -> libc::c_int;

    /**
     * Generate seccomp Berkley Packet Filter (BPF) code and export it to a file
     *
     * @param ctx the filter context
     * @param fd the destination fd
     *
     * This function generates seccomp Berkley Packer Filter (BPF) code and writes
     * it to the given fd.  Returns zero on success, negative values on failure.
     *
     */
    pub fn seccomp_export_bpf(ctx: *const scmp_filter_ctx, fd: libc::c_int) -> libc::c_int;
}

#[test]
fn does_it_even_work() {
    unsafe {
        let context = seccomp_init(SCMP_ACT_ALLOW);
        let comparator = scmp_arg_cmp {
            arg: 0,
            op: scmp_compare::SCMP_CMP_EQ,
            datum_a: 1000,
            datum_b: 0,
        };
        assert!(seccomp_rule_add(context, SCMP_ACT_KILL, 105, 1, comparator) == 0);
        assert!(seccomp_load(context) == 0);
        //assert!(libc::setuid(1000) == 0);
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
extern crate rand;
extern crate time;

#[derive(Debug)]
pub struct CohortResult<T: Clone> {
    duration: f64,
    result: T
}

impl<T: Clone> CohortResult<T> {
    pub fn new(duration: f64, result: &T) -> Self {
        CohortResult {
            duration: duration,
            result: result.clone()
        }
    }
}

#[derive(Debug)]
pub struct ExperimentResult<CurrentT: Clone, NewT: Clone> {
    current: CohortResult<CurrentT>,
    new: CohortResult<NewT>,
    name: &'static str
}

impl<CurrentT: Clone, NewT: Clone> ExperimentResult<CurrentT, NewT> {
    pub fn new(current: CohortResult<CurrentT>, new: CohortResult<NewT>, name: &'static str) -> Self {
        ExperimentResult {
            current: current,
            new: new,
            name: name
        }
    }
}

#[macro_export]
macro_rules! experiment {
    ($dexter_type:ident, $name:expr, current:$current:block new:$new:block) => {
        {
            use $crate::internal::rand::{thread_rng, Rng};
            use $crate::internal::time::{precise_time_ns};

            let mut rng = thread_rng();
            let mut did_one = false;
            let current_goes_first: bool = rng.gen();
            let mut current_val = None;
            let mut new_val = None;
            let mut current_duration = 0;
            let mut new_duration = 0;
            loop {
                if (current_goes_first || did_one) && !(current_goes_first && did_one) {
                    let start = precise_time_ns();
                    current_val = Some($current);
                    current_duration = precise_time_ns() - start;
                    if did_one {
                        break;
                    } else {
                        did_one = true;
                    }
                }
                if (!current_goes_first || did_one) && !(!current_goes_first && did_one) {
                    let start = precise_time_ns();
                    new_val = Some($new);
                    new_duration = precise_time_ns() - start;
                    if did_one {
                        break;
                    } else {
                        did_one = true;
                    }
                }
            }
            $dexter_type::publish(ExperimentResult::new(
                CohortResult::new(current_duration as f64 * 1e-9, &current_val.as_ref().unwrap()),
                CohortResult::new(new_duration as f64 * 1e-9, &new_val.as_ref().unwrap()),
                $name
            ));
            current_val.unwrap()
        }
    }
}

pub trait Dexter<CurrentT: Clone, NewT: Clone> {
    fn publish(_: ExperimentResult<CurrentT, NewT>) {}
}

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

    impl Dexter<String, String> for TestExperiment {
        fn publish(result: ExperimentResult<String, String>) {
            println!("{:?}", result);
        }
    }

    #[test]
    fn it_works() {
        let a = experiment!{
            TestExperiment,
            "experiment!",
            current: {
                println!("current went!");
                "current result".to_string()
            }
            new: {
                println!("new went!");
                "new result".to_string()
            }
        };
        println!("{}", a);
    }
}

#[doc(hidden)]
pub mod internal {
    pub use rand;
    pub use time;
}
<commit_msg>Changed from macro to function that takes closures as parameters<commit_after>#![allow(dead_code)]
extern crate rand;
extern crate time;

use rand::{thread_rng, Rng};
use time::{precise_time_ns};

#[derive(Debug)]
pub struct CohortResult<T: Clone> {
    pub duration: f64,
    pub result: T
}

impl<T: Clone> CohortResult<T> {
    pub fn new(duration: f64, result: &T) -> Self {
        CohortResult {
            duration: duration,
            result: result.clone()
        }
    }
}

#[derive(Debug)]
pub struct ExperimentResult<CurrentT: Clone, NewT: Clone> {
    pub current: CohortResult<CurrentT>,
    pub new: CohortResult<NewT>,
    pub name: &'static str
}

impl<CurrentT: Clone, NewT: Clone> ExperimentResult<CurrentT, NewT> {
    pub fn new(current: CohortResult<CurrentT>, new: CohortResult<NewT>, name: &'static str) -> Self {
        ExperimentResult {
            current: current,
            new: new,
            name: name
        }
    }
}

pub trait Experiment<CurrentResult: Clone, NewResult: Clone> {
    fn publish(_: ExperimentResult<CurrentResult, NewResult>) {}

    fn carry_out<C, N, Param>(name: &'static str, mut current: C, mut new: N, param: Param) -> CurrentResult
        where C: FnMut(Param) -> CurrentResult,
              N: FnMut(Param) -> NewResult,
              Param: Clone {
        let mut rng = thread_rng();
        let mut did_one = false;
        let current_goes_first: bool = rng.gen();
        let mut current_val = None;
        let mut new_val = None;
        let mut current_duration = 0;
        let mut new_duration = 0;
        loop {
            if (current_goes_first || did_one) && !(current_goes_first && did_one) {
                let start = precise_time_ns();
                current_val = Some(current(param.clone()));
                current_duration = precise_time_ns() - start;
                if did_one {
                    break;
                } else {
                    did_one = true;
                }
            }
            if (!current_goes_first || did_one) && !(!current_goes_first && did_one) {
                let start = precise_time_ns();
                new_val = Some(new(param.clone()));
                new_duration = precise_time_ns() - start;
                if did_one {
                    break;
                } else {
                    did_one = true;
                }
            }
        }
        Self::publish(ExperimentResult::new(
            CohortResult::new(current_duration as f64 * 1e-9, &current_val.as_ref().unwrap()),
            CohortResult::new(new_duration as f64 * 1e-9, &new_val.as_ref().unwrap()),
            name
        ));
        current_val.unwrap()
    }
}

#[cfg(test)]
mod test {
    use super::{Experiment, ExperimentResult};
    struct TestExperiment;

    impl Experiment<String, String> for TestExperiment {
        fn publish(result: ExperimentResult<String, String>) {
            println!("{:?}", result);
        }
    }

    #[test]
    fn it_works() {
        let a_str = "bagelman";
        let a = TestExperiment::carry_out(
            "experiment!",
            |_| {
                println!("current went!");
                a_str.to_string()
            },
            |_| {
                println!("new went!");
                a_str.to_string()
            },
            ()
        );
        println!("{}", a);
    }
}

#[doc(hidden)]
pub mod internal {
    pub use rand;
    pub use time;
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

extern crate abomonation;
extern crate timely;
extern crate time;
extern crate mmap;

use std::rc::Rc;

use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::pact::Exchange;
use timely::communication::*;

use timely::drain::DrainExt;

use abomonation::Abomonation;

pub mod graph;
mod typedrw;
// pub mod flattener;

pub use typedrw::TypedMemoryMap;
// use flattener::*;

// Algorithm 3 is an implementation of an instance of GenericJoin, a worst-case optimal join algorithm.

// The algorithm orders the attributes of the resulting relation, and for each prefix of these attributes
// produces the set of viable prefixes of output relations. The set of prefixes is updated by a new attribute
// by having each relation with that attribute propose extensions for each prefix, based on matching existing
// attributes within their relation. Proposals are then intersected, and surviving extended prefixes form the
// basis of the next iteration

// Informally, the algorithm looks like:
// 0. Let X be an empty relation over 0 attributes
// 1. For each output attribute A:
//     0. Let T be an initially empty set.
//     a. For each relation R containing A:
//         i. For each element x of X, let p(R, x) be the set of distinct values of A in pi_A(R join x),
//            that is, the distinct symbols R would propose to extend x.
//     b. For each element x of X, let r(x) be the relation R with the smallest p(R, x).
//     c. For each relation R containing A:
//         i. For each element x of X with r(x) = R, add (x join p(R, x)) to T.
//     d. For each relation R containing A:
//         i. For each element (x, y) of T, remove (x, y) if y is not in p(R, x).
//
// The important part of this algorithm is that step d.i should take roughly constant time.

// record-by-record prefix extension functionality
pub trait PrefixExtender {
    type Prefix;
    type Extension;

    // these are the parts required for the join algorithm
    fn count(&self, &Self::Prefix) -> u64;
    fn propose(&self, &Self::Prefix, &mut Vec<Self::Extension>);
    fn intersect(&self, &Self::Prefix, &mut Vec<Self::Extension>);

    // these are needed to tell timely dataflow how to route prefixes.
    // this object will be shared under an Rc<RefCell<...>> so we want
    // to give back a function, rather than provide a method ourself.
    type RoutingFunction: Fn(&Self::Prefix)->u64+'static;
    fn logic(&self) -> Rc<Self::RoutingFunction>;
}

// functionality required by the GenericJoin layer
pub trait StreamPrefixExtender<G: GraphBuilder> {
    type Prefix: Data+Abomonation;
    type Extension: Data+Abomonation;

    fn count(&self, Stream<G, (Self::Prefix, u64, u64)>, u64) -> Stream<G, (Self::Prefix, u64, u64)>;
    fn propose(&self, Stream<G, Self::Prefix>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)>;
    fn intersect(&self, Stream<G, (Self::Prefix, Vec<Self::Extension>)>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)>;
}

// implementation of StreamPrefixExtender for any (wrapped) PrefixExtender
impl<G: GraphBuilder, PE: PrefixExtender+'static> StreamPrefixExtender<G> for Rc<PE>
where PE::Prefix: Data+Abomonation,
      PE::Extension: Data+Abomonation, {
    type Prefix = PE::Prefix;
    type Extension = PE::Extension;

    fn count(&self, stream: Stream<G, (Self::Prefix, u64, u64)>, ident: u64) -> Stream<G, (Self::Prefix, u64, u64)> {
        let clone = self.clone();
        let logic = self.logic();
        let exch = Exchange::new(move |&(ref x,_,_)| (*logic)(x));
        stream.unary_stream(exch, format!("Count"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                output.give_at(&time, data.drain_temp().filter_map(|(p,c,i)| {
                    let nc = (*clone).count(&p);
                    if nc > c { Some((p,c,i)) }
                    else      { if nc > 0 { Some((p,nc,ident)) } else { None } }
                }));
            }
        })
    }

    fn propose(&self, stream: Stream<G, Self::Prefix>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)> {
        let clone = self.clone();
        let logic = self.logic();
        let exch = Exchange::new(move |x| (*logic)(x));
        stream.unary_stream(exch, format!("Propose"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                output.give_at(&time, data.drain_temp().map(|p| {
                    let mut vec = Vec::new();
                    (*clone).propose(&p, &mut vec);
                    (p, vec)
                }));
            }
        })
    }
    fn intersect(&self, stream: Stream<G, (Self::Prefix, Vec<Self::Extension>)>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)> {
        let logic = self.logic();
        let clone = self.clone();
        let exch = Exchange::new(move |&(ref x,_)| (*logic)(x));
        stream.unary_stream(exch, format!("Intersect"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                output.give_at(&time, data.drain_temp().filter_map(|(prefix, mut extensions)| {
                    (*clone).intersect(&prefix, &mut extensions);
                    if extensions.len() > 0 { Some((prefix, extensions)) } else { None }
                }));
            }
        })
    }
}

pub trait GenericJoinExt<G:GraphBuilder, P:Data+Abomonation> {
    fn extend<E: Data+Abomonation>(self, extenders: Vec<&StreamPrefixExtender<G, Prefix=P, Extension=E>>)
        -> Stream<G, (P, Vec<E>)>;
}

// A layer of GenericJoin, in which a collection of prefixes are extended by one attribute
impl<G: GraphBuilder, P:Data+Abomonation> GenericJoinExt<G, P> for Stream<G, P> {
    fn extend<E: Data+Abomonation>(self, extenders: Vec<&StreamPrefixExtender<G, Prefix=P, Extension=E>>)
        -> Stream<G, (P, Vec<E>)> {

        let mut counts = self.map(|p| (p, 1 << 31, 0));
        for (index,extender) in extenders.iter().enumerate() {
            counts = extender.count(counts, index as u64);
        }

        let parts = counts.partition(extenders.len() as u64, |&(_, _, i)| i);

        let mut results = Vec::new();
        for (index, part) in parts.into_iter().enumerate() {
            let nominations = part.map(|(x, _, _)| x);
            let mut extensions = extenders[index].propose(nominations);
            for other in (0..extenders.len()).filter(|&x| x != index) {
                extensions = extenders[other].intersect(extensions);
            }

            results.push(extensions);    // save extensions
        }

        self.builder().concatenate(results)
    }
}
<commit_msg>updated to pass buffers through where possible; new partition api<commit_after>#![allow(dead_code)]

extern crate abomonation;
extern crate timely;
extern crate time;
extern crate mmap;

use std::rc::Rc;

use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::pact::Exchange;
use timely::communication::*;

use timely::drain::DrainExt;

use abomonation::Abomonation;

pub mod graph;
mod typedrw;
// pub mod flattener;

pub use typedrw::TypedMemoryMap;
// use flattener::*;

// Algorithm 3 is an implementation of an instance of GenericJoin, a worst-case optimal join algorithm.

// The algorithm orders the attributes of the resulting relation, and for each prefix of these attributes
// produces the set of viable prefixes of output relations. The set of prefixes is updated by a new attribute
// by having each relation with that attribute propose extensions for each prefix, based on matching existing
// attributes within their relation. Proposals are then intersected, and surviving extended prefixes form the
// basis of the next iteration

// Informally, the algorithm looks like:
// 0. Let X be an empty relation over 0 attributes
// 1. For each output attribute A:
//     0. Let T be an initially empty set.
//     a. For each relation R containing A:
//         i. For each element x of X, let p(R, x) be the set of distinct values of A in pi_A(R join x),
//            that is, the distinct symbols R would propose to extend x.
//     b. For each element x of X, let r(x) be the relation R with the smallest p(R, x).
//     c. For each relation R containing A:
//         i. For each element x of X with r(x) = R, add (x join p(R, x)) to T.
//     d. For each relation R containing A:
//         i. For each element (x, y) of T, remove (x, y) if y is not in p(R, x).
//
// The important part of this algorithm is that step d.i should take roughly constant time.

// record-by-record prefix extension functionality
pub trait PrefixExtender {
    type Prefix;
    type Extension;

    // these are the parts required for the join algorithm
    fn count(&self, &Self::Prefix) -> u64;
    fn propose(&self, &Self::Prefix, &mut Vec<Self::Extension>);
    fn intersect(&self, &Self::Prefix, &mut Vec<Self::Extension>);

    // these are needed to tell timely dataflow how to route prefixes.
    // this object will be shared under an Rc<RefCell<...>> so we want
    // to give back a function, rather than provide a method ourself.
    type RoutingFunction: Fn(&Self::Prefix)->u64+'static;
    fn logic(&self) -> Rc<Self::RoutingFunction>;
}

// functionality required by the GenericJoin layer
pub trait StreamPrefixExtender<G: GraphBuilder> {
    type Prefix: Data+Abomonation;
    type Extension: Data+Abomonation;

    fn count(&self, Stream<G, (Self::Prefix, u64, u64)>, u64) -> Stream<G, (Self::Prefix, u64, u64)>;
    fn propose(&self, Stream<G, Self::Prefix>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)>;
    fn intersect(&self, Stream<G, (Self::Prefix, Vec<Self::Extension>)>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)>;
}

// implementation of StreamPrefixExtender for any (wrapped) PrefixExtender
impl<G: GraphBuilder, PE: PrefixExtender+'static> StreamPrefixExtender<G> for Rc<PE>
where PE::Prefix: Data+Abomonation,
      PE::Extension: Data+Abomonation, {
    type Prefix = PE::Prefix;
    type Extension = PE::Extension;

    fn count(&self, stream: Stream<G, (Self::Prefix, u64, u64)>, ident: u64) -> Stream<G, (Self::Prefix, u64, u64)> {
        let clone = self.clone();
        let logic = self.logic();
        let exch = Exchange::new(move |&(ref x,_,_)| (*logic)(x));
        stream.unary_stream(exch, format!("Count"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                for &mut (ref p, ref mut c, ref mut i) in data.iter_mut() {
                    let nc = (*clone).count(p);
                    if &nc < c {
                        *c = nc;
                        *i = ident;
                    }
                }
                data.retain(|x| x.1 > 0);
                output.give_vector_at(&time, data);
            }
        })
    }

    fn propose(&self, stream: Stream<G, Self::Prefix>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)> {
        let clone = self.clone();
        let logic = self.logic();
        let exch = Exchange::new(move |x| (*logic)(x));
        stream.unary_stream(exch, format!("Propose"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                output.give_at(&time, data.drain_temp().map(|p| {
                    let mut vec = Vec::new();
                    (*clone).propose(&p, &mut vec);
                    (p, vec)
                }));
            }
        })
    }
    fn intersect(&self, stream: Stream<G, (Self::Prefix, Vec<Self::Extension>)>) -> Stream<G, (Self::Prefix, Vec<Self::Extension>)> {
        let logic = self.logic();
        let clone = self.clone();
        let exch = Exchange::new(move |&(ref x,_)| (*logic)(x));
        stream.unary_stream(exch, format!("Intersect"), move |input, output| {
            while let Some((time, data)) = input.pull() {
                for &mut (ref prefix, ref mut extensions) in data.iter_mut() {
                    (*clone).intersect(prefix, extensions);
                }
                data.retain(|x| x.1.len() > 0);
                output.give_vector_at(&time, data);
            }
        })
    }
}

pub trait GenericJoinExt<G:GraphBuilder, P:Data+Abomonation> {
    fn extend<E: Data+Abomonation>(self, extenders: Vec<&StreamPrefixExtender<G, Prefix=P, Extension=E>>)
        -> Stream<G, (P, Vec<E>)>;
}

// A layer of GenericJoin, in which a collection of prefixes are extended by one attribute
impl<G: GraphBuilder, P:Data+Abomonation> GenericJoinExt<G, P> for Stream<G, P> {
    fn extend<E: Data+Abomonation>(self, extenders: Vec<&StreamPrefixExtender<G, Prefix=P, Extension=E>>)
        -> Stream<G, (P, Vec<E>)> {

        let mut counts = self.map(|p| (p, 1 << 31, 0));
        for (index,extender) in extenders.iter().enumerate() {
            counts = extender.count(counts, index as u64);
        }

        let parts = counts.partition(extenders.len() as u64, |(p, _, i)| (i, p));

        let mut results = Vec::new();
        for (index, nominations) in parts.into_iter().enumerate() {
            // let nominations = part.map(|(x, _, _)| x);
            let mut extensions = extenders[index].propose(nominations);
            for other in (0..extenders.len()).filter(|&x| x != index) {
                extensions = extenders[other].intersect(extensions);
            }

            results.push(extensions);    // save extensions
        }

        self.builder().concatenate(results)
    }
}
<|endoftext|>


<commit_before>use std::iter::FromIterator;
use std::num::Float;

use num::{Zero, One};

use number::Number;
use real::Real;
use datum::Datum;
use error::{RuntimeError, RuntimeErrorKind};
use runtime::{DatumCast, RDatum, DatumType};

pub trait PrimFunc {
    fn call(&self, &[RDatum]) -> Result<RDatum, RuntimeError>;
}

pub struct Fold<P> {
    fold: fn(&[P]) -> P
}

pub struct Fold1<P> {
    fold1: fn(&P, &[P]) -> P
}

pub struct Fold1Err<P> {
    fold1: fn(&P, &[P]) -> Result<P, RuntimeError>
}

pub struct F1<T0, R> {
    f1: fn(T0) -> R
}

pub struct R1<R> {
    f1: fn(&RDatum) -> R
}

impl<T> PrimFunc for Fold<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold;
        p_args.map(|v| f(v.as_slice()).wrap())
    }
}

impl PrimFunc for Fold<RDatum> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let f = self.fold;
        Ok(f(args))
    }
}

impl<T> PrimFunc for Fold1<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold1;
        p_args.and_then(|v|
            if v.len() < 1 {
                Err(RuntimeError {
                    kind: RuntimeErrorKind::NumArgs,
                    desc: "Expected at least 1 arguments, received 0".to_string()
                })
            } else {
                Ok(f(&v[0], &v[1..]).wrap())
            }
        )
    }
}

impl<T> PrimFunc for Fold1Err<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold1;
        p_args.and_then(|v|
            if v.len() < 1 {
                Err(RuntimeError {
                    kind: RuntimeErrorKind::NumArgs,
                    desc: "Expected at least 1 arguments, received 0".to_string()
                })
            } else {
                f(&v[0], &v[1..]).map(|res| res.wrap())
            }
        )
    }
}

impl<R: DatumCast> PrimFunc for R1<R> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        let f = self.f1;

        Ok(f(&args[0]).wrap())
    }
}

impl<T0: DatumCast> PrimFunc for F1<T0, RDatum> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        DatumCast::unwrap(&args[0]).map(self.f1)
    }
}

impl<T0: DatumCast, R: DatumCast> PrimFunc for F1<T0, R> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        let f = self.f1;
        DatumCast::unwrap(&args[0]).map(|v| f(v).wrap())
    }
}

fn add(args: &[Number]) -> Number {
    let mut sum:Number = Zero::zero();
    for a in args.iter() {
        sum = &sum + a;
    }
    return sum;
}

/// `(+ n0 n1 ...)`
pub static PRIM_ADD:Fold<Number> = Fold { fold: add };

fn mul(args: &[Number]) -> Number {
    let mut product:Number = One::one();
    for a in args.iter() {
        product = &product * a;
    }
    return product;
}

/// `(* n0 n1 ...)`
pub static PRIM_MUL:Fold<Number> = Fold { fold: mul };

fn sub(arg0: &Number, args: &[Number]) -> Number {
    if args.len() == 0 {
        return -arg0;
    }
    let mut sum:Number = arg0.clone();
    for a in args.iter() {
        sum = &sum - a;
    }
    return sum;
}

/// `(- n0 n1 ...)`
pub static PRIM_SUB:Fold1<Number> = Fold1 { fold1: sub };

fn div(arg0: &Number, args: &[Number]) -> Result<Number, RuntimeError> {
    if args.len() == 0 {
        if arg0.is_exact() && arg0.is_zero() {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::DivideByZero,
                desc: "Tried to divied by 0".to_string()
            });
        }
        return Ok(-arg0);
    }

    let mut product:Number = arg0.clone();
    for a in args.iter() {
        if a.is_exact() && a.is_zero() {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::DivideByZero,
                desc: "Tried to divied by 0".to_string()
            });
        }
        product = &product / a;
    }

    return Ok(product);
}

/// `(/ n0 n1 ...)`
pub static PRIM_DIV:Fold1Err<Number> = Fold1Err { fold1: div };

fn list(args: &[RDatum]) -> RDatum {
    FromIterator::from_iter(args.iter().map(Clone::clone))
}

/// `(list a0 a1 ...)`
pub static PRIM_LIST:Fold<RDatum> = Fold { fold: list };

fn car(arg: (RDatum, RDatum)) -> RDatum {
    arg.0
}

/// `(car x)`
pub static PRIM_CAR: F1<(RDatum, RDatum), RDatum> = F1 { f1: car };

fn cdr(arg: (RDatum, RDatum)) -> RDatum {
    arg.1
}

/// `(cdr x)`
pub static PRIM_CDR: F1<(RDatum, RDatum), RDatum> = F1 { f1: cdr };

fn zero(arg: Number) -> bool {
    arg.is_zero()
}

/// `(zero? x)`
pub static PRIM_ZERO: F1<Number, bool> = F1 { f1: zero };

fn is_real(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(_)) => true,
        _ => false
    }
}

/// `(real? x)`
pub static PRIM_REAL: R1<bool> = R1 { f1: is_real };

fn is_rational(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(Real::Flonum(f))) => f.is_finite(),
        &Datum::Num(Number::Real(_)) => true,
        _ => false
    }
}

/// `(rational? x)`
pub static PRIM_RATIONAL: R1<bool> = R1 { f1: is_rational };

fn is_integer(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(ref r)) => r.is_integer(),
        _ => false
    }
}

/// `(integer? x)`
pub static PRIM_INTEGER: R1<bool> = R1 { f1: is_integer };

macro_rules! impl_typecheck {
    ($static_name:ident, $func_name:ident, $type_name:ident) => (
        fn $func_name(arg: &RDatum) -> bool {
            DatumType::get_type(arg) == DatumType::$type_name
        }

        pub static $static_name: R1<bool> = R1 { f1: $func_name };
    )
}

impl_typecheck!(PRIM_BOOLEAN, is_boolean, Bool);
impl_typecheck!(PRIM_PAIR, is_pair, Pair);
impl_typecheck!(PRIM_SYMBOL, is_symbol, Sym);
impl_typecheck!(PRIM_NUMBER, is_number, Num);
impl_typecheck!(PRIM_CHAR, is_char, Char);
impl_typecheck!(PRIM_STRING, is_string, String);
impl_typecheck!(PRIM_VECTOR, is_vector, Vector);
impl_typecheck!(PRIM_PROCEDURE, is_procedure, Callable);
impl_typecheck!(PRIM_NULL, is_null, Null);

/// Lists all primitive functions with its name
pub fn libprimitive() -> Vec<(&'static str, &'static (PrimFunc + 'static))> {
    vec![
        ("+", &PRIM_ADD),
        ("-", &PRIM_SUB),
        ("*", &PRIM_MUL),
        ("/", &PRIM_DIV),
        ("list", &PRIM_LIST),
        ("boolean?", &PRIM_BOOLEAN),
        ("pair?", &PRIM_PAIR),
        ("symbol?", &PRIM_SYMBOL),
        ("number?", &PRIM_NUMBER),
        ("char?", &PRIM_CHAR),
        ("string?", &PRIM_STRING),
        ("vector?", &PRIM_VECTOR),
        ("procedure?", &PRIM_PROCEDURE),
        ("null?", &PRIM_NULL),
        ("car", &PRIM_CAR),
        ("cdr", &PRIM_CDR),
        ("zero?", &PRIM_ZERO),
        // complex? is synonym to number?
        ("complex?", &PRIM_NUMBER),
        ("real?", &PRIM_REAL),
        ("rational?", &PRIM_RATIONAL),
        ("integer?", &PRIM_INTEGER)
    ]
}
<commit_msg>Make R1 more generic<commit_after>use std::iter::FromIterator;
use std::num::Float;

use num::{Zero, One};

use number::Number;
use real::Real;
use datum::Datum;
use error::{RuntimeError, RuntimeErrorKind};
use runtime::{DatumCast, RDatum, DatumType};

pub trait PrimFunc {
    fn call(&self, &[RDatum]) -> Result<RDatum, RuntimeError>;
}

pub struct Fold<P> {
    fold: fn(&[P]) -> P
}

pub struct Fold1<P> {
    fold1: fn(&P, &[P]) -> P
}

pub struct Fold1Err<P> {
    fold1: fn(&P, &[P]) -> Result<P, RuntimeError>
}

pub struct F1<T0, R> {
    f1: fn(T0) -> R
}

pub struct R1<T0, R> {
    r1: fn(&T0) -> R
}

impl<T> PrimFunc for Fold<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold;
        p_args.map(|v| f(v.as_slice()).wrap())
    }
}

impl PrimFunc for Fold<RDatum> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let f = self.fold;
        Ok(f(args))
    }
}

impl<T> PrimFunc for Fold1<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold1;
        p_args.and_then(|v|
            if v.len() < 1 {
                Err(RuntimeError {
                    kind: RuntimeErrorKind::NumArgs,
                    desc: "Expected at least 1 arguments, received 0".to_string()
                })
            } else {
                Ok(f(&v[0], &v[1..]).wrap())
            }
        )
    }
}

impl<T> PrimFunc for Fold1Err<T> where T: DatumCast {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        let p_args:Result<Vec<T>, RuntimeError> = args.iter().map(DatumCast::unwrap).collect();
        let f = self.fold1;
        p_args.and_then(|v|
            if v.len() < 1 {
                Err(RuntimeError {
                    kind: RuntimeErrorKind::NumArgs,
                    desc: "Expected at least 1 arguments, received 0".to_string()
                })
            } else {
                f(&v[0], &v[1..]).map(|res| res.wrap())
            }
        )
    }
}

impl<R: DatumCast> PrimFunc for R1<RDatum, R> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        let f = self.r1;

        Ok(f(&args[0]).wrap())
    }
}

impl<T0: DatumCast> PrimFunc for F1<T0, RDatum> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        DatumCast::unwrap(&args[0]).map(self.f1)
    }
}

impl<T0: DatumCast, R: DatumCast> PrimFunc for F1<T0, R> {
    fn call(&self, args: &[RDatum]) -> Result<RDatum, RuntimeError> {
        if args.len() != 1 {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::NumArgs,
                desc: format!("Expected 1 argument, received {:?}", args.len())
            });
        }
        let f = self.f1;
        DatumCast::unwrap(&args[0]).map(|v| f(v).wrap())
    }
}

fn add(args: &[Number]) -> Number {
    let mut sum:Number = Zero::zero();
    for a in args.iter() {
        sum = &sum + a;
    }
    return sum;
}

/// `(+ n0 n1 ...)`
pub static PRIM_ADD:Fold<Number> = Fold { fold: add };

fn mul(args: &[Number]) -> Number {
    let mut product:Number = One::one();
    for a in args.iter() {
        product = &product * a;
    }
    return product;
}

/// `(* n0 n1 ...)`
pub static PRIM_MUL:Fold<Number> = Fold { fold: mul };

fn sub(arg0: &Number, args: &[Number]) -> Number {
    if args.len() == 0 {
        return -arg0;
    }
    let mut sum:Number = arg0.clone();
    for a in args.iter() {
        sum = &sum - a;
    }
    return sum;
}

/// `(- n0 n1 ...)`
pub static PRIM_SUB:Fold1<Number> = Fold1 { fold1: sub };

fn div(arg0: &Number, args: &[Number]) -> Result<Number, RuntimeError> {
    if args.len() == 0 {
        if arg0.is_exact() && arg0.is_zero() {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::DivideByZero,
                desc: "Tried to divied by 0".to_string()
            });
        }
        return Ok(-arg0);
    }

    let mut product:Number = arg0.clone();
    for a in args.iter() {
        if a.is_exact() && a.is_zero() {
            return Err(RuntimeError {
                kind: RuntimeErrorKind::DivideByZero,
                desc: "Tried to divied by 0".to_string()
            });
        }
        product = &product / a;
    }

    return Ok(product);
}

/// `(/ n0 n1 ...)`
pub static PRIM_DIV:Fold1Err<Number> = Fold1Err { fold1: div };

fn list(args: &[RDatum]) -> RDatum {
    FromIterator::from_iter(args.iter().map(Clone::clone))
}

/// `(list a0 a1 ...)`
pub static PRIM_LIST:Fold<RDatum> = Fold { fold: list };

fn car(arg: (RDatum, RDatum)) -> RDatum {
    arg.0
}

/// `(car x)`
pub static PRIM_CAR: F1<(RDatum, RDatum), RDatum> = F1 { f1: car };

fn cdr(arg: (RDatum, RDatum)) -> RDatum {
    arg.1
}

/// `(cdr x)`
pub static PRIM_CDR: F1<(RDatum, RDatum), RDatum> = F1 { f1: cdr };

fn zero(arg: Number) -> bool {
    arg.is_zero()
}

/// `(zero? x)`
pub static PRIM_ZERO: F1<Number, bool> = F1 { f1: zero };

fn is_real(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(_)) => true,
        _ => false
    }
}

/// `(real? x)`
pub static PRIM_REAL: R1<RDatum, bool> = R1 { r1: is_real };

fn is_rational(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(Real::Flonum(f))) => f.is_finite(),
        &Datum::Num(Number::Real(_)) => true,
        _ => false
    }
}

/// `(rational? x)`
pub static PRIM_RATIONAL: R1<RDatum, bool> = R1 { r1: is_rational };

fn is_integer(arg: &RDatum) -> bool {
    match arg {
        &Datum::Num(Number::Real(ref r)) => r.is_integer(),
        _ => false
    }
}

/// `(integer? x)`
pub static PRIM_INTEGER: R1<RDatum, bool> = R1 { r1: is_integer };

macro_rules! impl_typecheck {
    ($static_name:ident, $func_name:ident, $type_name:ident) => (
        fn $func_name(arg: &RDatum) -> bool {
            DatumType::get_type(arg) == DatumType::$type_name
        }

        pub static $static_name: R1<RDatum, bool> = R1 { r1: $func_name };
    )
}

impl_typecheck!(PRIM_BOOLEAN, is_boolean, Bool);
impl_typecheck!(PRIM_PAIR, is_pair, Pair);
impl_typecheck!(PRIM_SYMBOL, is_symbol, Sym);
impl_typecheck!(PRIM_NUMBER, is_number, Num);
impl_typecheck!(PRIM_CHAR, is_char, Char);
impl_typecheck!(PRIM_STRING, is_string, String);
impl_typecheck!(PRIM_VECTOR, is_vector, Vector);
impl_typecheck!(PRIM_PROCEDURE, is_procedure, Callable);
impl_typecheck!(PRIM_NULL, is_null, Null);

/// Lists all primitive functions with its name
pub fn libprimitive() -> Vec<(&'static str, &'static (PrimFunc + 'static))> {
    vec![
        ("+", &PRIM_ADD),
        ("-", &PRIM_SUB),
        ("*", &PRIM_MUL),
        ("/", &PRIM_DIV),
        ("list", &PRIM_LIST),
        ("boolean?", &PRIM_BOOLEAN),
        ("pair?", &PRIM_PAIR),
        ("symbol?", &PRIM_SYMBOL),
        ("number?", &PRIM_NUMBER),
        ("char?", &PRIM_CHAR),
        ("string?", &PRIM_STRING),
        ("vector?", &PRIM_VECTOR),
        ("procedure?", &PRIM_PROCEDURE),
        ("null?", &PRIM_NULL),
        ("car", &PRIM_CAR),
        ("cdr", &PRIM_CDR),
        ("zero?", &PRIM_ZERO),
        // complex? is synonym to number?
        ("complex?", &PRIM_NUMBER),
        ("real?", &PRIM_REAL),
        ("rational?", &PRIM_RATIONAL),
        ("integer?", &PRIM_INTEGER)
    ]
}
<|endoftext|>


<commit_before>extern crate libc;

use libc::{c_char, c_int, c_void};

#[repr(C)]
#[derive(Copy)]
pub struct PamHandle;

#[repr(C)]
#[derive(Copy)]
pub struct PamConv {
    pub conv: *const c_void,
    pub data_ptr: *mut c_void
}

extern "C" {
    /* --------------             pam_appl.h            ------------- */
    /* -------------- The Linux-PAM Framework layer API ------------- */

    pub fn pam_start(service_name: *const c_char, user: *const c_char,
        pam_conversation: *const PamConv, pamh: *mut *const PamHandle) -> c_int;

    pub fn pam_end(pamh: *mut PamHandle, pam_status: c_int) -> c_int;

    /* Authentication API's */
    pub fn pam_authenticate(pamh: *mut PamHandle, flags: c_int) -> c_int;

    pub fn pam_setcred(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Account Management API's */
    pub fn pam_acct_mgmt(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Session Management API's */
    pub fn pam_open_session(pamh: *mut PamHandle, flags: c_int) -> c_int;

    pub fn pam_close_session(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Password Management API's */
    pub fn pam_chauthtok(pamh: *mut PamHandle, flags: c_int) -> c_int;
}
<commit_msg>Added some more ffi methods<commit_after>extern crate libc;

use libc::{c_char, c_int, c_void};

#[repr(C)]
#[derive(Copy)]
pub struct PamHandle;

#[repr(C)]
#[derive(Copy)]
pub struct PamConv {
    pub conv: *const c_void,
    pub data_ptr: *mut c_void
}

extern "C" {
    /* ------------------------ pam_appl.h -------------------------- */
    /* -------------- The Linux-PAM Framework layer API ------------- */
    pub fn pam_start(service_name: *const c_char, user: *const c_char,
        pam_conversation: *const PamConv, pamh: *mut *const PamHandle) -> c_int;

    pub fn pam_end(pamh: *mut PamHandle, pam_status: c_int) -> c_int;

    /* Authentication API's */
    pub fn pam_authenticate(pamh: *mut PamHandle, flags: c_int) -> c_int;

    pub fn pam_setcred(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Account Management API's */
    pub fn pam_acct_mgmt(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Session Management API's */
    pub fn pam_open_session(pamh: *mut PamHandle, flags: c_int) -> c_int;

    pub fn pam_close_session(pamh: *mut PamHandle, flags: c_int) -> c_int;

    /* Password Management API's */
    pub fn pam_chauthtok(pamh: *mut PamHandle, flags: c_int) -> c_int;
    /* ------------------------ pam_appl.h -------------------------- */

    /* ----------------------- _pam_types.h ------------------------- */
    /* ---------- Common Linux-PAM application/module PI ------------ */
    pub fn pam_set_item(pamh: *mut PamHandle, item_type: c_int, item: *const c_void) -> c_int;

    pub fn pam_get_item(pamh: *const PamHandle, item_type: c_int, item: *const *const c_void) -> c_int;

    pub fn pam_strerror(pamh: *mut PamHandle, errnum: c_int) -> *const c_char;

    pub fn pam_putenv(pamh: *mut PamHandle, name_value: *const c_char) -> c_int;

    pub fn pam_getenv(pamh: *mut PamHandle, name: *const c_char) -> *const c_char;

    pub fn pam_getenvlist(pamh: *mut PamHandle) -> *const *const c_char;
    /* ----------------------- _pam_types.h ------------------------- */

    /* ----------------------- pam_modules.h ------------------------ */
    /* -------------------- The Linux-PAM Module PI ----------------- */

    /*pub fn pam_set_data(pamh: *mut PamHandle, module_data_name: *const c_char,
        data: *mut c_void, cleanup: extern fn()  void (*cleanup)(pamh: *mut PamHandle, void *data,
    			     int error_status));*/

    pub fn pam_get_data(pamh: *const PamHandle, module_data_name: *const c_char, data: *const *const c_void);

    pub fn pam_get_user(pamh: *mut PamHandle, user: *const *const c_char, prompt: *const c_char);
    /* ----------------------- pam_modules.h ------------------------ */
}
<|endoftext|>


<commit_before>//! [![github]](https://github.com/dtolnay/serde-yaml) [![crates-io]](https://crates.io/crates/serde-yaml) [![docs-rs]](https://docs.rs/serde-yaml)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//!

//!
//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: http://yaml.org
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```
//! use std::collections::BTreeMap;
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     // You have some type.
//!     let mut map = BTreeMap::new();
//!     map.insert("x".to_string(), 1.0);
//!     map.insert("y".to_string(), 2.0);
//!
//!     // Serialize it to a YAML string.
//!     let s = serde_yaml::to_string(&map)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     // Deserialize it back to a Rust type.
//!     let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
//!     assert_eq!(map, deserialized_map);
//!     Ok(())
//! }
//! ```
//!
//! ## Using Serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point {
//!     x: f64,
//!     y: f64,
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     let point = Point { x: 1.0, y: 2.0 };
//!
//!     let s = serde_yaml::to_string(&point)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     let deserialized_point: Point = serde_yaml::from_str(&s)?;
//!     assert_eq!(point, deserialized_point);
//!     Ok(())
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.16")]
#![deny(missing_docs)]
// Suppressed clippy_pedantic lints
#![allow(
    // private Deserializer::next
    clippy::should_implement_trait,
    // things are often more readable this way
    clippy::cast_lossless,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::single_match_else,
    clippy::use_self,
    // code is acceptable
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    clippy::cast_sign_loss,
    // not practical
    clippy::indexing_slicing,
    clippy::missing_docs_in_private_items,
    // not stable
    clippy::checked_conversions,
    clippy::empty_enum,
    // meh, some things won't fail
    clippy::unwrap_used,
    // noisy
    clippy::missing_errors_doc,
    clippy::must_use_candidate,
    // we support older compilers
    clippy::manual_strip,
    clippy::match_like_matches_macro,
)]

pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
pub use crate::error::{Error, Location, Result};
pub use crate::ser::{to_string, to_vec, to_writer, Serializer};
pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};

#[doc(inline)]
pub use crate::mapping::Mapping;

/// Entry points for deserializing with pre-existing state.
///
/// These functions are only exposed this way because we don't yet expose a
/// Deserializer type. Data formats that have a public Deserializer should not
/// copy these signatures.
pub mod seed {
    pub use super::de::{from_reader_seed, from_slice_seed, from_str_seed};
}

mod de;
mod error;
pub mod mapping;
mod number;
mod path;
mod ser;
mod value;
<commit_msg>Remove no longer triggered clippy suppressions<commit_after>//! [![github]](https://github.com/dtolnay/serde-yaml) [![crates-io]](https://crates.io/crates/serde-yaml) [![docs-rs]](https://docs.rs/serde-yaml)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//!

//!
//! This crate is a Rust library for using the [Serde] serialization framework
//! with data in [YAML] file format.
//!
//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
//! is a pure Rust YAML 1.2 implementation.
//!
//! [Serde]: https://github.com/serde-rs/serde
//! [YAML]: http://yaml.org
//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
//!
//! # Examples
//!
//! ```
//! use std::collections::BTreeMap;
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     // You have some type.
//!     let mut map = BTreeMap::new();
//!     map.insert("x".to_string(), 1.0);
//!     map.insert("y".to_string(), 2.0);
//!
//!     // Serialize it to a YAML string.
//!     let s = serde_yaml::to_string(&map)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     // Deserialize it back to a Rust type.
//!     let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
//!     assert_eq!(map, deserialized_map);
//!     Ok(())
//! }
//! ```
//!
//! ## Using Serde derive
//!
//! It can also be used with Serde's serialization code generator `serde_derive` to
//! handle structs and enums defined in your own program.
//!
//! ```
//! # use serde_derive::{Serialize, Deserialize};
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
//! struct Point {
//!     x: f64,
//!     y: f64,
//! }
//!
//! fn main() -> Result<(), serde_yaml::Error> {
//!     let point = Point { x: 1.0, y: 2.0 };
//!
//!     let s = serde_yaml::to_string(&point)?;
//!     assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
//!
//!     let deserialized_point: Point = serde_yaml::from_str(&s)?;
//!     assert_eq!(point, deserialized_point);
//!     Ok(())
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.16")]
#![deny(missing_docs)]
// Suppressed clippy_pedantic lints
#![allow(
    // private Deserializer::next
    clippy::should_implement_trait,
    // things are often more readable this way
    clippy::cast_lossless,
    clippy::module_name_repetitions,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::single_match_else,
    // code is acceptable
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    // noisy
    clippy::missing_errors_doc,
    clippy::must_use_candidate,
)]

pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
pub use crate::error::{Error, Location, Result};
pub use crate::ser::{to_string, to_vec, to_writer, Serializer};
pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};

#[doc(inline)]
pub use crate::mapping::Mapping;

/// Entry points for deserializing with pre-existing state.
///
/// These functions are only exposed this way because we don't yet expose a
/// Deserializer type. Data formats that have a public Deserializer should not
/// copy these signatures.
pub mod seed {
    pub use super::de::{from_reader_seed, from_slice_seed, from_str_seed};
}

mod de;
mod error;
pub mod mapping;
mod number;
mod path;
mod ser;
mod value;
<|endoftext|>


<commit_before>#![feature(ip_addr)]

use std::fmt;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

// A network
#[derive(Debug)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

pub struct Ipv4Network {
    addr: Ipv4Addr,
    prefix: u8,
}

pub struct Ipv6Network {
    addr: Ipv6Addr,
    prefix: u8,
}

impl Ipv4Network {
    fn new(addr: Ipv4Addr, prefix: u8) -> Ipv4Network {
        Ipv4Network { addr: addr, prefix: prefix }
    }

    fn ip(&self) -> &Ipv4Addr {
        &(self.addr)
    }

    fn prefix(&self) -> u8 {
        self.prefix
    }
}

impl Ipv6Network {
    fn new(addr: Ipv6Addr, prefix: u8) -> Ipv6Network {
        Ipv6Network { addr: addr, prefix: prefix }
    }

    fn ip(&self) -> &Ipv6Addr {
        &(self.addr)
    }

    fn prefix(&self) -> u8 {
        self.prefix
    }
}

impl IpNetwork {
    pub fn new(ip: IpAddr, prefix: u8) -> IpNetwork {
        match ip {
            IpAddr::V4(a) => IpNetwork::V4(Ipv4Network::new(a, prefix)),
            IpAddr::V6(a) => IpNetwork::V6(Ipv6Network::new(a, prefix)),
        }
    }

    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(*a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(*a.ip()),
        }
    }

    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }
}

impl fmt::Debug for Ipv4Network {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.ip(), self.prefix())
    }
}

impl fmt::Debug for Ipv6Network {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.ip(), self.prefix())
    }
}

#[cfg(test)]
mod test {
    use std::net::{Ipv4Addr, Ipv6Addr};
    use super::*;

    #[test]
    fn test_create_v4() {
        let cidr = Ipv4Network::new(Ipv4Addr::new(77, 88, 21, 11), 24);
        assert_eq!(cidr.prefix(), 24);
    }

    #[test]
    fn test_create_v6() {
        let cidr = Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 24);
        assert_eq!(cidr.prefix(), 24);
    }
}
<commit_msg>Rename tests<commit_after>#![feature(ip_addr)]

use std::fmt;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

// A network
#[derive(Debug)]
pub enum IpNetwork {
    V4(Ipv4Network),
    V6(Ipv6Network),
}

pub struct Ipv4Network {
    addr: Ipv4Addr,
    prefix: u8,
}

pub struct Ipv6Network {
    addr: Ipv6Addr,
    prefix: u8,
}

impl Ipv4Network {
    fn new(addr: Ipv4Addr, prefix: u8) -> Ipv4Network {
        Ipv4Network { addr: addr, prefix: prefix }
    }

    fn ip(&self) -> &Ipv4Addr {
        &(self.addr)
    }

    fn prefix(&self) -> u8 {
        self.prefix
    }
}

impl Ipv6Network {
    fn new(addr: Ipv6Addr, prefix: u8) -> Ipv6Network {
        Ipv6Network { addr: addr, prefix: prefix }
    }

    fn ip(&self) -> &Ipv6Addr {
        &(self.addr)
    }

    fn prefix(&self) -> u8 {
        self.prefix
    }
}

impl IpNetwork {
    pub fn new(ip: IpAddr, prefix: u8) -> IpNetwork {
        match ip {
            IpAddr::V4(a) => IpNetwork::V4(Ipv4Network::new(a, prefix)),
            IpAddr::V6(a) => IpNetwork::V6(Ipv6Network::new(a, prefix)),
        }
    }

    pub fn ip(&self) -> IpAddr {
        match *self {
            IpNetwork::V4(ref a) => IpAddr::V4(*a.ip()),
            IpNetwork::V6(ref a) => IpAddr::V6(*a.ip()),
        }
    }

    pub fn prefix(&self) -> u8 {
        match *self {
            IpNetwork::V4(ref a) => a.prefix(),
            IpNetwork::V6(ref a) => a.prefix(),
        }
    }
}

impl fmt::Debug for Ipv4Network {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.ip(), self.prefix())
    }
}

impl fmt::Debug for Ipv6Network {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.ip(), self.prefix())
    }
}

#[cfg(test)]
mod test {
    use std::net::{Ipv4Addr, Ipv6Addr};
    use super::*;

    #[test]
    fn create_v4() {
        let cidr = Ipv4Network::new(Ipv4Addr::new(77, 88, 21, 11), 24);
        assert_eq!(cidr.prefix(), 24);
    }

    #[test]
    fn create_v6() {
        let cidr = Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 24);
        assert_eq!(cidr.prefix(), 24);
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
extern crate collections;
extern crate url;
#[phase(plugin, link)] extern crate log;

pub mod connection;
pub mod channel;
pub mod framing;
pub mod table;
pub mod protocol;
pub mod session;
<commit_msg>Don’t require a crate we don’t use.<commit_after>#![feature(phase)]
extern crate collections;
// extern crate url;
#[phase(plugin, link)] extern crate log;

pub mod connection;
pub mod channel;
pub mod framing;
pub mod table;
pub mod protocol;
pub mod session;
<|endoftext|>