<commit_before>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Macros and wrapper functions for dealing with ioctls.

use std::os::raw::*;
use std::os::unix::io::AsRawFd;

use libc;

/// Raw macro to declare the expression that calculates an ioctl number
#[macro_export]
macro_rules! ioctl_expr {
    ($dir:expr, $ty:expr, $nr:expr, $size:expr) => {
        (($dir << $crate::ioctl::_IOC_DIRSHIFT)
            | ($ty << $crate::ioctl::_IOC_TYPESHIFT)
            | ($nr << $crate::ioctl::_IOC_NRSHIFT)
            | ($size << $crate::ioctl::_IOC_SIZESHIFT)) as ::std::os::raw::c_ulong
    };
}

/// Raw macro to declare a function that returns an ioctl number.
#[macro_export]
macro_rules! ioctl_ioc_nr {
    ($name:ident, $dir:expr, $ty:expr, $nr:expr, $size:expr) => {
        #[allow(non_snake_case)]
        pub fn $name() -> ::std::os::raw::c_ulong {
            ioctl_expr!($dir, $ty, $nr, $size)
        }
    };
    ($name:ident, $dir:expr, $ty:expr, $nr:expr, $size:expr, $($v:ident),+) => {
        #[allow(non_snake_case)]
        pub fn $name($($v: ::std::os::raw::c_uint),+) -> ::std::os::raw::c_ulong {
            ioctl_expr!($dir, $ty, $nr, $size)
        }
    };
}

/// Declare an ioctl that transfers no data.
#[macro_export]
macro_rules! ioctl_io_nr {
    ($name:ident, $ty:expr, $nr:expr) => {
        ioctl_ioc_nr!($name, $crate::ioctl::_IOC_NONE, $ty, $nr, 0);
    };
    ($name:ident, $ty:expr, $nr:expr, $($v:ident),+) => {
        ioctl_ioc_nr!($name, $crate::ioctl::_IOC_NONE, $ty, $nr, 0, $($v),+);
    };
}

/// Declare an ioctl that reads data.
#[macro_export]
macro_rules! ioctl_ior_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

/// Declare an ioctl that writes data.
#[macro_export]
macro_rules! ioctl_iow_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

/// Declare an ioctl that reads and writes data.
#[macro_export]
macro_rules! ioctl_iowr_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ | $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ | $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

pub const _IOC_NRBITS: c_uint = 8;
pub const _IOC_TYPEBITS: c_uint = 8;
pub const _IOC_SIZEBITS: c_uint = 14;
pub const _IOC_DIRBITS: c_uint = 2;
pub const _IOC_NRMASK: c_uint = 255;
pub const _IOC_TYPEMASK: c_uint = 255;
pub const _IOC_SIZEMASK: c_uint = 16383;
pub const _IOC_DIRMASK: c_uint = 3;
pub const _IOC_NRSHIFT: c_uint = 0;
pub const _IOC_TYPESHIFT: c_uint = 8;
pub const _IOC_SIZESHIFT: c_uint = 16;
pub const _IOC_DIRSHIFT: c_uint = 30;
pub const _IOC_NONE: c_uint = 0;
pub const _IOC_WRITE: c_uint = 1;
pub const _IOC_READ: c_uint = 2;
pub const IOC_IN: c_uint = 1073741824;
pub const IOC_OUT: c_uint = 2147483648;
pub const IOC_INOUT: c_uint = 3221225472;
pub const IOCSIZE_MASK: c_uint = 1073676288;
pub const IOCSIZE_SHIFT: c_uint = 16;

/// Run an ioctl with no arguments.
pub unsafe fn ioctl<F: AsRawFd>(fd: &F, nr: c_ulong) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, 0)
}

/// Run an ioctl with a single value argument.
pub unsafe fn ioctl_with_val<F: AsRawFd>(fd: &F, nr: c_ulong, arg: c_ulong) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg)
}

/// Run an ioctl with an immutable reference.
pub unsafe fn ioctl_with_ref<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: &T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *const T as *const c_void)
}

/// Run an ioctl with a mutable reference.
pub unsafe fn ioctl_with_mut_ref<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: &mut T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *mut T as *mut c_void)
}

/// Run an ioctl with a raw pointer.
pub unsafe fn ioctl_with_ptr<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: *const T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *const c_void)
}

/// Run an ioctl with a mutable raw pointer.
pub unsafe fn ioctl_with_mut_ptr<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: *mut T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *mut c_void)
}

#[cfg(test)]
mod tests {
    const TUNTAP: ::std::os::raw::c_uint = 0x54;
    const VHOST: ::std::os::raw::c_uint = 0xaf;
    const EVDEV: ::std::os::raw::c_uint = 0x45;

    ioctl_io_nr!(VHOST_SET_OWNER, VHOST, 0x01);
    ioctl_ior_nr!(TUNGETFEATURES, TUNTAP, 0xcf, ::std::os::raw::c_uint);
    ioctl_iow_nr!(TUNSETQUEUE, TUNTAP, 0xd9, ::std::os::raw::c_int);
    ioctl_iowr_nr!(VHOST_GET_VRING_BASE, VHOST, 0x12, ::std::os::raw::c_int);

    ioctl_ior_nr!(EVIOCGBIT, EVDEV, 0x20 + evt, [u8; 128], evt);
    ioctl_io_nr!(FAKE_IOCTL_2_ARG, EVDEV, 0x01 + x + y, x, y);

    #[test]
    fn ioctl_macros() {
        assert_eq!(0x0000af01, VHOST_SET_OWNER());
        assert_eq!(0x800454cf, TUNGETFEATURES());
        assert_eq!(0x400454d9, TUNSETQUEUE());
        assert_eq!(0xc004af12, VHOST_GET_VRING_BASE());

        assert_eq!(0x80804522, EVIOCGBIT(2));
        assert_eq!(0x00004509, FAKE_IOCTL_2_ARG(3, 5));
    }
}
<commit_msg>sys_util: ioctl: Make clippy clean<commit_after>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Macros and wrapper functions for dealing with ioctls.

use std::os::raw::*;
use std::os::unix::io::AsRawFd;

use libc;

/// Raw macro to declare the expression that calculates an ioctl number
#[macro_export]
macro_rules! ioctl_expr {
    ($dir:expr, $ty:expr, $nr:expr, $size:expr) => {
        (($dir << $crate::ioctl::_IOC_DIRSHIFT)
            | ($ty << $crate::ioctl::_IOC_TYPESHIFT)
            | ($nr << $crate::ioctl::_IOC_NRSHIFT)
            | ($size << $crate::ioctl::_IOC_SIZESHIFT)) as ::std::os::raw::c_ulong
    };
}

/// Raw macro to declare a function that returns an ioctl number.
#[macro_export]
macro_rules! ioctl_ioc_nr {
    ($name:ident, $dir:expr, $ty:expr, $nr:expr, $size:expr) => {
        #[allow(non_snake_case)]
        pub fn $name() -> ::std::os::raw::c_ulong {
            ioctl_expr!($dir, $ty, $nr, $size)
        }
    };
    ($name:ident, $dir:expr, $ty:expr, $nr:expr, $size:expr, $($v:ident),+) => {
        #[allow(non_snake_case)]
        pub fn $name($($v: ::std::os::raw::c_uint),+) -> ::std::os::raw::c_ulong {
            ioctl_expr!($dir, $ty, $nr, $size)
        }
    };
}

/// Declare an ioctl that transfers no data.
#[macro_export]
macro_rules! ioctl_io_nr {
    ($name:ident, $ty:expr, $nr:expr) => {
        ioctl_ioc_nr!($name, $crate::ioctl::_IOC_NONE, $ty, $nr, 0);
    };
    ($name:ident, $ty:expr, $nr:expr, $($v:ident),+) => {
        ioctl_ioc_nr!($name, $crate::ioctl::_IOC_NONE, $ty, $nr, 0, $($v),+);
    };
}

/// Declare an ioctl that reads data.
#[macro_export]
macro_rules! ioctl_ior_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

/// Declare an ioctl that writes data.
#[macro_export]
macro_rules! ioctl_iow_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

/// Declare an ioctl that reads and writes data.
#[macro_export]
macro_rules! ioctl_iowr_nr {
    ($name:ident, $ty:expr, $nr:expr, $size:ty) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ | $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32
        );
    };
    ($name:ident, $ty:expr, $nr:expr, $size:ty, $($v:ident),+) => {
        ioctl_ioc_nr!(
            $name,
            $crate::ioctl::_IOC_READ | $crate::ioctl::_IOC_WRITE,
            $ty,
            $nr,
            ::std::mem::size_of::<$size>() as u32,
            $($v),+
        );
    };
}

pub const _IOC_NRBITS: c_uint = 8;
pub const _IOC_TYPEBITS: c_uint = 8;
pub const _IOC_SIZEBITS: c_uint = 14;
pub const _IOC_DIRBITS: c_uint = 2;
pub const _IOC_NRMASK: c_uint = 255;
pub const _IOC_TYPEMASK: c_uint = 255;
pub const _IOC_SIZEMASK: c_uint = 16383;
pub const _IOC_DIRMASK: c_uint = 3;
pub const _IOC_NRSHIFT: c_uint = 0;
pub const _IOC_TYPESHIFT: c_uint = 8;
pub const _IOC_SIZESHIFT: c_uint = 16;
pub const _IOC_DIRSHIFT: c_uint = 30;
pub const _IOC_NONE: c_uint = 0;
pub const _IOC_WRITE: c_uint = 1;
pub const _IOC_READ: c_uint = 2;
pub const IOC_IN: c_uint = 1_073_741_824;
pub const IOC_OUT: c_uint = 2_147_483_648;
pub const IOC_INOUT: c_uint = 3_221_225_472;
pub const IOCSIZE_MASK: c_uint = 1_073_676_288;
pub const IOCSIZE_SHIFT: c_uint = 16;

/// Run an ioctl with no arguments.
pub unsafe fn ioctl<F: AsRawFd>(fd: &F, nr: c_ulong) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, 0)
}

/// Run an ioctl with a single value argument.
pub unsafe fn ioctl_with_val<F: AsRawFd>(fd: &F, nr: c_ulong, arg: c_ulong) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg)
}

/// Run an ioctl with an immutable reference.
pub unsafe fn ioctl_with_ref<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: &T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *const T as *const c_void)
}

/// Run an ioctl with a mutable reference.
pub unsafe fn ioctl_with_mut_ref<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: &mut T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *mut T as *mut c_void)
}

/// Run an ioctl with a raw pointer.
pub unsafe fn ioctl_with_ptr<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: *const T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *const c_void)
}

/// Run an ioctl with a mutable raw pointer.
pub unsafe fn ioctl_with_mut_ptr<F: AsRawFd, T>(fd: &F, nr: c_ulong, arg: *mut T) -> c_int {
    libc::ioctl(fd.as_raw_fd(), nr, arg as *mut c_void)
}

#[cfg(test)]
mod tests {
    const TUNTAP: ::std::os::raw::c_uint = 0x54;
    const VHOST: ::std::os::raw::c_uint = 0xaf;
    const EVDEV: ::std::os::raw::c_uint = 0x45;

    ioctl_io_nr!(VHOST_SET_OWNER, VHOST, 0x01);
    ioctl_ior_nr!(TUNGETFEATURES, TUNTAP, 0xcf, ::std::os::raw::c_uint);
    ioctl_iow_nr!(TUNSETQUEUE, TUNTAP, 0xd9, ::std::os::raw::c_int);
    ioctl_iowr_nr!(VHOST_GET_VRING_BASE, VHOST, 0x12, ::std::os::raw::c_int);

    ioctl_ior_nr!(EVIOCGBIT, EVDEV, 0x20 + evt, [u8; 128], evt);
    ioctl_io_nr!(FAKE_IOCTL_2_ARG, EVDEV, 0x01 + x + y, x, y);

    #[test]
    fn ioctl_macros() {
        assert_eq!(0x0000af01, VHOST_SET_OWNER());
        assert_eq!(0x800454cf, TUNGETFEATURES());
        assert_eq!(0x400454d9, TUNSETQUEUE());
        assert_eq!(0xc004af12, VHOST_GET_VRING_BASE());

        assert_eq!(0x80804522, EVIOCGBIT(2));
        assert_eq!(0x00004509, FAKE_IOCTL_2_ARG(3, 5));
    }
}
<|endoftext|>


<commit_before>use seax_svm::svm::cell::SVMCell;
use seax_svm::slist::List;

/// Trait for AST nodes.
pub trait ASTNode {
    /// Compile this node to a list of SVM expressions
    fn compile(self)                        -> List<SVMCell>;

    /// Pretty-print this node
    fn prettyprint(&self)                   -> String {
        prettyprint_level(&self, 0usize)
    }

    /// Pretty-print this node at the desired indent level
    fn print_level(&self, level: usize)     -> String;
}

/// Expression
///
/// All Seax Scheme expressions are one of the following
///  + Nested S-Expressions
///  + Identifiers
///  + Lists
///  + Numbers
///     - signed int
///     - unsigned int
///     - floating-point
///  + Characters
///  + Strings
///  TODO: implement the entire Scheme 'numeric tower'
///  TODO: macros should happen
#[deriving(Clone, PartialEq)]
pub enum ExprNode {
    Root(RootNode),
    SExpr(SExprNode),
    Name(NameNode),
    List(ListNode),
    IntConst(IntNode),
    UIntConst(UIntNode),
    FloatConst(FloatNode),
    BoolConst(BoolNode),
    StringConst(StringNode),
    CharConst(CharNode),
}

/// AST node for the root of a program's AST
#[deriving(Clone, PartialEq)]
pub struct RootNode { pub exprs: Vec<ExprNode> }

/// AST node for an S-expression.
///
/// This includes function application, assignment,
/// function definition, et cetera...Scheme is not a complexl anguage.
#[deriving(Clone, PartialEq)]
pub struct SExprNode {
    pub operator: NameNode,
    pub operands: Vec<ExprNode>,
}

/// AST node for a list literal
#[deriving(Clone, PartialEq)]
pub struct ListNode { pub elements: Vec<ExprNode> }

/// AST node for an identifier
#[deriving(Clone, PartialEq)]
pub struct NameNode { pub name: String }

/// AST node for an integer constant
#[deriving(Clone, PartialEq)]
pub struct IntNode { pub value: isize }

/// AST node for an unsigned integer constant
#[deriving(Clone, PartialEq)]
pub struct UIntNode { pub value: usize }

/// AST node for a floating-point constant
#[deriving(Clone, PartialEq)]
pub struct FloatNode { pub value: f64 }

/// AST node for a boolean constant
#[deriving(Clone, PartialEq)]
pub struct BoolNode { pub value: bool }

/// AST node for a character constant
#[deriving(Clone, PartialEq)]
pub struct CharNode { pub value: char }

<commit_msg>Compile now carries error values<commit_after>use seax_svm::svm::cell::SVMCell;
use seax_svm::slist::List;

/// Trait for AST nodes.
pub trait ASTNode {
    /// Compile this node to a list of SVM expressions
    fn compile(self)                        -> Result<SVMCell, &'static str>;

    /// Pretty-print this node
    fn prettyprint(&self)                   -> String {
        prettyprint_level(&self, 0usize)
    }

    /// Pretty-print this node at the desired indent level
    fn print_level(&self, level: usize)     -> String;
}

/// Expression
///
/// All Seax Scheme expressions are one of the following
///  + Nested S-Expressions
///  + Identifiers
///  + Lists
///  + Numbers
///     - signed int
///     - unsigned int
///     - floating-point
///  + Characters
///  + Strings
///  TODO: implement the entire Scheme 'numeric tower'
///  TODO: macros should happen
#[deriving(Clone, PartialEq)]
pub enum ExprNode {
    Root(RootNode),
    SExpr(SExprNode),
    Name(NameNode),
    List(ListNode),
    IntConst(IntNode),
    UIntConst(UIntNode),
    FloatConst(FloatNode),
    BoolConst(BoolNode),
    StringConst(StringNode),
    CharConst(CharNode),
}

/// AST node for the root of a program's AST
#[deriving(Clone, PartialEq)]
pub struct RootNode { pub exprs: Vec<ExprNode> }

/// AST node for an S-expression.
///
/// This includes function application, assignment,
/// function definition, et cetera...Scheme is not a complexl anguage.
#[deriving(Clone, PartialEq)]
pub struct SExprNode {
    pub operator: NameNode,
    pub operands: Vec<ExprNode>,
}

/// AST node for a list literal
#[deriving(Clone, PartialEq)]
pub struct ListNode { pub elements: Vec<ExprNode> }

/// AST node for an identifier
#[deriving(Clone, PartialEq)]
pub struct NameNode { pub name: String }

/// AST node for an integer constant
#[deriving(Clone, PartialEq)]
pub struct IntNode { pub value: isize }

/// AST node for an unsigned integer constant
#[deriving(Clone, PartialEq)]
pub struct UIntNode { pub value: usize }

/// AST node for a floating-point constant
#[deriving(Clone, PartialEq)]
pub struct FloatNode { pub value: f64 }

/// AST node for a boolean constant
#[deriving(Clone, PartialEq)]
pub struct BoolNode { pub value: bool }

/// AST node for a character constant
#[deriving(Clone, PartialEq)]
pub struct CharNode { pub value: char }

<|endoftext|>


<commit_before>/// `Builder!` macro
///
/// Use in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with generics.
    //
    // Receive parsed fields of normal struct from `__diesel_parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            column_name: $column_name:ident,
            field_ty: $field_ty:ty,
            field_kind: $field_kind:ident,
        })+],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                /// Setter-method
                ///
                /// auto-generated by [derive_builder](https://crates.io/crates/derive_builder)
                fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Struct without generics.
    //
    // Receive parsed fields of normal struct from `__diesel_parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = (),
        ),
        fields = [$({
            field_name: $field_name:ident,
            column_name: $column_name:ident,
            field_ty: $field_ty:ty,
            field_kind: $field_kind:ident,
        })+],
    ) => {
        #[allow(dead_code)]
        impl $struct_name {
            $(
                /// Setter-method
                ///
                /// auto-generated by [derive_builder](https://crates.io/crates/derive_builder)
                fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __diesel_parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __diesel_parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<commit_msg>make setter-methods public<commit_after>/// `Builder!` macro
///
/// Use in combination with [custom_derive][custom_derive].
///
/// [custom_derive]: https://crates.io/crates/custom_derive
#[macro_export]
macro_rules! Builder {
    // Strip empty argument list if given (Passed by custom_derive macro)
    (() $($body:tt)*) => {
        Builder! { $($body)* }
    };

    // Strip meta items, pub (if present) and struct from definition
    (
        $(#[$ignore:meta])*
        $(pub)* struct $($body:tt)*
    ) => {
        Builder! { $($body)* }
    };

    // Struct with generics.
    //
    // Receive parsed fields of normal struct from `__diesel_parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = ($($generics:ident),*),
        ),
        fields = [$({
            field_name: $field_name:ident,
            column_name: $column_name:ident,
            field_ty: $field_ty:ty,
            field_kind: $field_kind:ident,
        })+],
    ) => {
        #[allow(dead_code)]
        impl<$($generics),*> $struct_name<$($generics),*> {
            $(
                /// Setter-method
                ///
                /// auto-generated by [derive_builder](https://crates.io/crates/derive_builder)
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Struct without generics.
    //
    // Receive parsed fields of normal struct from `__diesel_parse_struct_body`
    // and add implementation.
    //
    // These patterns must appear above those which start with an ident to
    // compile.
    (
        (
            struct_name = $struct_name:ident,
            generics = (),
        ),
        fields = [$({
            field_name: $field_name:ident,
            column_name: $column_name:ident,
            field_ty: $field_ty:ty,
            field_kind: $field_kind:ident,
        })+],
    ) => {
        #[allow(dead_code)]
        impl $struct_name {
            $(
                /// Setter-method
                ///
                /// auto-generated by [derive_builder](https://crates.io/crates/derive_builder)
                pub fn $field_name<VALUE: Into<$field_ty>>(mut self, value: VALUE) -> Self {
                    self.$field_name = value.into();
                    self
                }
            )+
        }
    };

    // Handle struct with generics
    (
        $struct_name:ident <$($generics:ident),*>
        $body:tt $(;)*
    ) => {
        __diesel_parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = ($($generics),*),
            ),
            callback = Builder,
            body = $body,
        }
    };

    // Handle struct with no generics
    (
        $struct_name:ident
        $body:tt $(;)*
    ) => {
        __diesel_parse_struct_body! {
            (
                struct_name = $struct_name,
                generics = (),
            ),
            callback = Builder,
            body = $body,
        }
    };
}
<|endoftext|>


<commit_before>use super::managed_display::ManagedDisplay;
use entities::{ EntitiesState, EntityID, ComponentID, NativeComponentType };
use nalgebra::na::{ Mat4, Vec3, Eye };
use std::collections::{ HashSet, HashMap };
use std::sync::Arc;
use super::sprite_displayer::SpriteDisplayer;
use super::Drawable;

pub struct DisplaySystem {
	display: Arc<ManagedDisplay>,
	sprites: HashMap<ComponentID, SpriteDisplayer>
}

impl DisplaySystem {
	pub fn new(display: Arc<ManagedDisplay>, state: &EntitiesState)
		-> DisplaySystem
	{
		DisplaySystem {
			display: display.clone(),
			sprites: HashMap::new()
		}
	}

	pub fn draw(&mut self, state: &EntitiesState, elapsed: &u64)
	{
		self.update_sprite_displayers(state);

		let camera = DisplaySystem::get_camera(state);

	 	for (cmp, sprite) in self.sprites.iter() {
	 		let pos = DisplaySystem::get_position(state, &state.get_owner(cmp).unwrap());
	 		let translationMatrix = Mat4::new(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, pos.x, pos.y, pos.z, 1.0);
			sprite.draw(&(translationMatrix * camera));
		}
	}

	fn update_sprite_displayers(&mut self, state: &EntitiesState)
	{
		// getting the list of all sprite displayer components
		let listOfComponents = state.get_components_iter()
            .filter(|c| state.is_component_visible(*c).unwrap())
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "spriteDisplay", _ => false })
			.map(|c| c.clone())
			.collect::<HashSet<EntityID>>();

		// removing from the list the elements that have disappeared
		{	let toRemove = self.sprites.keys().filter(|e| !listOfComponents.contains(e.clone())).map(|e| e.clone()).collect::<Vec<EntityID>>();
			for c in toRemove.move_iter() {
				self.sprites.remove(&c);
			}
		}

		// adding elements that are not yet created
		{	let toCreate = listOfComponents.iter().filter(|e| !self.sprites.contains_key(e.clone())).map(|e| e.clone()).collect::<Vec<EntityID>>();
			for spriteDisplayComponent in toCreate.move_iter() {
				// getting the name of the texture
				let textureName = match state.get(&spriteDisplayComponent, "texture") { Ok(&::entities::String(ref s)) => s, _ => continue };

				let mut spriteDisplayer = SpriteDisplayer::new(self.display.clone(), textureName.as_slice()).unwrap();

				// getting coordinates
				spriteDisplayer.set_rectangle_coords(
					match state.get(&spriteDisplayComponent, "leftX") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => -0.5 },
					match state.get(&spriteDisplayComponent, "topY") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 1.0 },
					match state.get(&spriteDisplayComponent, "rightX") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 0.5 },
					match state.get(&spriteDisplayComponent, "bottomY") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 0.0 }
				);

				// inserting in sprites list
				self.sprites.insert(spriteDisplayComponent.clone(), spriteDisplayer);
			}
		}
	}

	/// returns the camera matrix of the scene
	fn get_camera(state: &EntitiesState)
		-> Mat4<f32>
	{
		state
			.get_components_iter()

			// filter out non-visible components
			.filter(|c| state.is_component_visible(*c).unwrap())

			// take only the "camera" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "camera", _ => false })

			// get the component with the highest priority
			.max_by(|c| match state.get(*c, "priority") { Ok(&::entities::Number(ref n)) => (((*n) * 1000f64) as int), _ => -99999999 })

			// get the matrix of this component and check its type
			.and_then(|e| match state.get(e, "matrix") { Ok(&::entities::List(ref data)) => Some(data), _ => None })

			// check the type of each element in the matrix and creates an array
			.map(|data| data.iter().filter_map(|elem| match elem { &::entities::Number(ref n) => Some(n.clone() as f32), _ => None }).collect() )

			// turn into matrix
			.map(|array: Vec<f32>| Mat4::new(*array.get(0), *array.get(1), *array.get(2), *array.get(3), *array.get(4), *array.get(5), *array.get(6), *array.get(7), *array.get(8), *array.get(9), *array.get(10), *array.get(11), *array.get(12), *array.get(13), *array.get(14), *array.get(15)))

			// return identity if the option is empty
			.unwrap_or_else(|| Eye::new_identity(4))
	}

	/// returns the position of an entity
	fn get_position(state: &EntitiesState, id: &EntityID)
		-> Vec3<f32>
	{
		state
			.get_components_iter()

			// filter out non-visible components
			.filter(|c| state.is_component_visible(*c).unwrap())

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), Ok(&::entities::Number(ref z)))
					=> Some(Vec3::new(*x as f32, *y as f32, *z as f32)),
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec3::new(*x as f32, *y as f32, 0.0)),
				_ => None
			})

			// add all the elements together
			.fold(Vec3::new(0.0, 0.0, 0.0), |vec, a| vec + a)
	}
}
<commit_msg>Bugfix in display system<commit_after>use super::managed_display::ManagedDisplay;
use entities::{ EntitiesState, EntityID, ComponentID, NativeComponentType };
use nalgebra::na::{ Mat4, Vec3, Eye };
use std::collections::{ HashSet, HashMap };
use std::sync::Arc;
use super::sprite_displayer::SpriteDisplayer;
use super::Drawable;

pub struct DisplaySystem {
	display: Arc<ManagedDisplay>,
	sprites: HashMap<ComponentID, SpriteDisplayer>
}

impl DisplaySystem {
	pub fn new(display: Arc<ManagedDisplay>, state: &EntitiesState)
		-> DisplaySystem
	{
		DisplaySystem {
			display: display.clone(),
			sprites: HashMap::new()
		}
	}

	pub fn draw(&mut self, state: &EntitiesState, elapsed: &u64)
	{
		self.update_sprite_displayers(state);

		let camera = DisplaySystem::get_camera(state);

	 	for (cmp, sprite) in self.sprites.iter() {
	 		let pos = DisplaySystem::get_position(state, &state.get_owner(cmp).unwrap());
	 		let translationMatrix = Mat4::new(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, pos.x, pos.y, pos.z, 1.0);
			sprite.draw(&(translationMatrix * camera));
		}
	}

	fn update_sprite_displayers(&mut self, state: &EntitiesState)
	{
		// getting the list of all sprite displayer components
		let listOfComponents = state.get_components_iter()
            .filter(|c| state.is_component_visible(*c).unwrap())
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "spriteDisplay", _ => false })
			.map(|c| c.clone())
			.collect::<HashSet<ComponentID>>();

		// removing from the list the elements that have disappeared
		{	let toRemove = self.sprites.keys().filter(|e| !listOfComponents.contains(e.clone())).map(|e| e.clone()).collect::<Vec<ComponentID>>();
			for c in toRemove.move_iter() {
				self.sprites.remove(&c);
			}
		}

		// adding elements that are not yet created
		{	let toCreate = listOfComponents.iter().filter(|e| !self.sprites.contains_key(e.clone())).map(|e| e.clone()).collect::<Vec<ComponentID>>();
			for spriteDisplayComponent in toCreate.move_iter() {
				// getting the name of the texture
				let textureName = match state.get(&spriteDisplayComponent, "texture") { Ok(&::entities::String(ref s)) => s, _ => continue };

				let mut spriteDisplayer = SpriteDisplayer::new(self.display.clone(), textureName.as_slice()).unwrap();

				// getting coordinates
				spriteDisplayer.set_rectangle_coords(
					match state.get(&spriteDisplayComponent, "leftX") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => -0.5 },
					match state.get(&spriteDisplayComponent, "topY") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 1.0 },
					match state.get(&spriteDisplayComponent, "rightX") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 0.5 },
					match state.get(&spriteDisplayComponent, "bottomY") { Ok(&::entities::Number(ref nb)) => *nb as f32, _ => 0.0 }
				);

				// inserting in sprites list
				self.sprites.insert(spriteDisplayComponent.clone(), spriteDisplayer);
			}
		}
	}

	/// returns the camera matrix of the scene
	fn get_camera(state: &EntitiesState)
		-> Mat4<f32>
	{
		state
			.get_components_iter()

			// filter out non-visible components
			.filter(|c| state.is_component_visible(*c).unwrap())

			// take only the "camera" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "camera", _ => false })

			// get the component with the highest priority
			.max_by(|c| match state.get(*c, "priority") { Ok(&::entities::Number(ref n)) => (((*n) * 1000f64) as int), _ => -99999999 })

			// get the matrix of this component and check its type
			.and_then(|e| match state.get(e, "matrix") { Ok(&::entities::List(ref data)) => Some(data), _ => None })

			// check the type of each element in the matrix and creates an array
			.map(|data| data.iter().filter_map(|elem| match elem { &::entities::Number(ref n) => Some(n.clone() as f32), _ => None }).collect() )

			// turn into matrix
			.map(|array: Vec<f32>| Mat4::new(*array.get(0), *array.get(1), *array.get(2), *array.get(3), *array.get(4), *array.get(5), *array.get(6), *array.get(7), *array.get(8), *array.get(9), *array.get(10), *array.get(11), *array.get(12), *array.get(13), *array.get(14), *array.get(15)))

			// return identity if the option is empty
			.unwrap_or_else(|| Eye::new_identity(4))
	}

	/// returns the position of an entity
	fn get_position(state: &EntitiesState, id: &EntityID)
		-> Vec3<f32>
	{
		state
			.get_components_iter()

			// filter out non-visible components
			.filter(|c| state.is_component_visible(*c).unwrap())

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), Ok(&::entities::Number(ref z)))
					=> Some(Vec3::new(*x as f32, *y as f32, *z as f32)),
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec3::new(*x as f32, *y as f32, 0.0)),
				_ => None
			})

			// add all the elements together
			.fold(Vec3::new(0.0, 0.0, 0.0), |vec, a| vec + a)
	}
}
<|endoftext|>


<commit_before>use std;
use std::iter::IntoIterator;

use value::{Value, ToValue, Tuple, ToTuple, Relation};
use interpreter;
use interpreter::{EveFn,ToExpression};

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum ConstraintOp {
    LT,
    LTE,
    EQ,
    NEQ,
    GT,
    GTE,
}

#[derive(Clone, Debug)]
pub enum Ref {
    Constant{value: Value},
    Value{clause: usize, column: usize},
    Tuple{clause: usize},
    Relation{clause: usize},
}

impl Ref {
    fn resolve<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {

        match *self {
            Ref::Constant{ref value} => {
                value
            },
            Ref::Value{clause, column} => {
                match result[clause] {
                    Value::Tuple(ref tuple) => {
                        &tuple[column]
                    },
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Tuple{clause} => {
                let value = &result[clause];
                match *value {
                    Value::Tuple(..) => value,
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Relation{clause} =>{
                let value = &result[clause];
                match *value {
                    Value::Relation(..) => value,
                    _ => panic!("Expected a relation"),
                }
            },
        }
    }
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub my_column: usize,
    pub op: ConstraintOp,
    pub other_ref: Ref,
}

impl Constraint {

    // Resolves the RHS reference in the constraint to a value
    fn prepare<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {
        self.other_ref.resolve(result)
    }

    // bearing in mind that Value is only PartialOrd so this may do weird things with NaN
    fn test(&self, my_row: &Vec<Value>, other_value: &Value) -> bool {
        let my_value = &my_row[self.my_column];
        match self.op {
            ConstraintOp::LT => my_value < other_value,
            ConstraintOp::LTE => my_value <= other_value,
            ConstraintOp::EQ => my_value == other_value,
            ConstraintOp::NEQ => my_value != other_value,
            ConstraintOp::GT => my_value > other_value,
            ConstraintOp::GTE => my_value >= other_value,
        }
    }
}

#[derive(Clone, Debug)]
pub struct Source {
    pub relation: usize,
    pub constraints: Vec<Constraint>,
}

impl Source {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Relation {

        let prepared: Vec<&Value> = self.constraints.iter()
                                                    .map(|constraint| constraint.prepare(result))
                                                    .collect();
        let input = inputs[self.relation];
        input.iter().filter(|row| self.constraints
                                      .iter()
                                      .zip(prepared.iter())
                                      .all(|(constraint, value)| constraint.test(row, value) ) )
                    .map(|row| row.clone())
                    .collect()
    }
}

#[derive(Clone)]
pub struct Call {
    pub fun: EveFn,
    pub args: CallArgs,
}

impl std::fmt::Debug for Call {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        formatter.write_str(&*format!("Call{{fun: {:?}, args:{:?}}}", self.fun, self.args))
    }
}

impl Call {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references and covert to an expression vector
        let args: Vec<interpreter::Expression> = self.args.iter()
                                                           .map(|arg_ref| arg_ref.resolve(result).to_expr())
                                                           .collect();

        let call = interpreter::Call{fun: self.fun.clone(), args: args};

        interpreter::evaluate(&interpreter::Expression::Call(call))
    }
}

#[derive(Clone)]
pub enum CallArg {
    Ref(Ref),
    Call(Call),
}

pub type CallArgs = Vec<CallArg>;

impl CallArg {
    fn resolve(&self, result: &Vec<Value>) -> Value {
        match self {
            &CallArg::Ref(ref arg_ref) => arg_ref.resolve(result).clone(),
            &CallArg::Call(ref arg_call) => arg_call.eval(result).clone(),
        }
    }
}

impl std::fmt::Debug for CallArg {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        match self {
            &CallArg::Ref(ref x) => formatter.write_str(&*format!("{:?}",x)),
            &CallArg::Call(ref x) => formatter.write_str(&*format!("{:?}",x)),
        }
    }
}

#[derive(Clone, Debug)]
pub enum Clause {
    Tuple(Source),
    Relation(Source),
    Call(Call),
}

impl Clause {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Clause::Tuple(ref source) => {
                let relation = source.constrained_to(inputs, result);
                relation.into_iter().map(|tuple| Value::Tuple(tuple)).collect()
            },
            Clause::Relation(ref source) => {
                let relation = source.constrained_to(inputs, result);
                vec![Value::Relation(relation)]
            },
            Clause::Call(ref call) => {
                let value = call.eval(result).to_tuple().to_value();
                vec![value]
            }
        }
    }
}

pub trait ToClause { fn to_clause(self) -> Clause; }

impl ToClause for Clause { fn to_clause(self) -> Clause { self } }
impl ToClause for Call { fn to_clause(self) -> Clause { Clause::Call(self) } }

// Macro for creating clause vectors
#[macro_export]
macro_rules! clausevec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x.to_clause());
            )*
            temp_vec
        }
    };
}

#[derive(Clone, Debug)]
pub struct Query {
    pub clauses: Vec<Clause>,
}

// an iter over results of the query, where each result is either:
// * a `max_len` tuple indicating a valid result
// * a smaller tuple indicating a backtrack point
pub struct QueryIter<'a> {
    query: &'a Query,
    inputs: Vec<&'a Relation>,
    max_len: usize, // max length of a result
    now_len: usize, // ixes[0..now_len] and values[0..now_len] are all valid for the next result
    has_next: bool, // are there any more results to be found
    ixes: Vec<usize>, // index of the value last returned by each clause
    values: Vec<Vec<Value>>, // the constrained relations representing each clause
}

impl Query {
    pub fn iter<'a>(&'a self, inputs: Vec<&'a Relation>) -> QueryIter {
        let max_len = self.clauses.len();
        QueryIter{
            query: &self,
            inputs: inputs,
            max_len: max_len,
            now_len: 0,
            has_next: true, // can always return at least the early fail
            ixes: vec![0; max_len],
            values: vec![vec![]; max_len]
        }
    }
}

impl<'a> Iterator for QueryIter<'a> {
    type Item = Tuple;

    fn next(&mut self) -> Option<Tuple> {
        if !self.has_next { return None };

        let mut result = vec![];

        // set known values
        for i in (0 .. self.now_len) {
            result.push(self.values[i][self.ixes[i]].clone());
        }

        // determine the values that changed since last time
        for i in (self.now_len .. self.max_len) {
            let values = self.query.clauses[i].constrained_to(&self.inputs, &result);
            if values.len() == 0 {
                break;
            } else {
                self.now_len = i + 1;
                result.push(values[0].clone());
                self.values[i] = values;
                self.ixes[i] = 0;
            }
        }

        // see if there is a next result
        self.has_next = false;
        for i in (0 .. self.now_len).rev() {
            let ix = self.ixes[i] + 1;
            if ix < self.values[i].len() {
                self.ixes[i] = ix;
                self.has_next = true;
                self.now_len = i + 1;
                break;
            }
        }

        Some(result)
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None) // ie no hints
    }
}<commit_msg>Removed ToClause<commit_after>use std;
use std::iter::IntoIterator;

use value::{Value, ToValue, Tuple, ToTuple, Relation};
use interpreter;
use interpreter::{EveFn,ToExpression};

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum ConstraintOp {
    LT,
    LTE,
    EQ,
    NEQ,
    GT,
    GTE,
}

#[derive(Clone, Debug)]
pub enum Ref {
    Constant{value: Value},
    Value{clause: usize, column: usize},
    Tuple{clause: usize},
    Relation{clause: usize},
}

impl Ref {
    fn resolve<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {

        match *self {
            Ref::Constant{ref value} => {
                value
            },
            Ref::Value{clause, column} => {
                match result[clause] {
                    Value::Tuple(ref tuple) => {
                        &tuple[column]
                    },
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Tuple{clause} => {
                let value = &result[clause];
                match *value {
                    Value::Tuple(..) => value,
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Relation{clause} =>{
                let value = &result[clause];
                match *value {
                    Value::Relation(..) => value,
                    _ => panic!("Expected a relation"),
                }
            },
        }
    }
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub my_column: usize,
    pub op: ConstraintOp,
    pub other_ref: Ref,
}

impl Constraint {

    // Resolves the RHS reference in the constraint to a value
    fn prepare<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {
        self.other_ref.resolve(result)
    }

    // bearing in mind that Value is only PartialOrd so this may do weird things with NaN
    fn test(&self, my_row: &Vec<Value>, other_value: &Value) -> bool {
        let my_value = &my_row[self.my_column];
        match self.op {
            ConstraintOp::LT => my_value < other_value,
            ConstraintOp::LTE => my_value <= other_value,
            ConstraintOp::EQ => my_value == other_value,
            ConstraintOp::NEQ => my_value != other_value,
            ConstraintOp::GT => my_value > other_value,
            ConstraintOp::GTE => my_value >= other_value,
        }
    }
}

#[derive(Clone, Debug)]
pub struct Source {
    pub relation: usize,
    pub constraints: Vec<Constraint>,
}

impl Source {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Relation {

        let prepared: Vec<&Value> = self.constraints.iter()
                                                    .map(|constraint| constraint.prepare(result))
                                                    .collect();
        let input = inputs[self.relation];
        input.iter().filter(|row| self.constraints
                                      .iter()
                                      .zip(prepared.iter())
                                      .all(|(constraint, value)| constraint.test(row, value) ) )
                    .map(|row| row.clone())
                    .collect()
    }
}

#[derive(Clone)]
pub struct Call {
    pub fun: EveFn,
    pub args: CallArgs,
}

impl std::fmt::Debug for Call {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        formatter.write_str(&*format!("Call{{fun: {:?}, args:{:?}}}", self.fun, self.args))
    }
}

impl Call {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references and covert to an expression vector
        let args: Vec<interpreter::Expression> = self.args.iter()
                                                           .map(|arg_ref| arg_ref.resolve(result).to_expr())
                                                           .collect();

        let call = interpreter::Call{fun: self.fun.clone(), args: args};

        interpreter::evaluate(&interpreter::Expression::Call(call))
    }
}

#[derive(Clone)]
pub enum CallArg {
    Ref(Ref),
    Call(Call),
}

pub type CallArgs = Vec<CallArg>;

impl CallArg {
    fn resolve(&self, result: &Vec<Value>) -> Value {
        match self {
            &CallArg::Ref(ref arg_ref) => arg_ref.resolve(result).clone(),
            &CallArg::Call(ref arg_call) => arg_call.eval(result).clone(),
        }
    }
}

impl std::fmt::Debug for CallArg {
    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        match self {
            &CallArg::Ref(ref x) => formatter.write_str(&*format!("{:?}",x)),
            &CallArg::Call(ref x) => formatter.write_str(&*format!("{:?}",x)),
        }
    }
}

#[derive(Clone, Debug)]
pub enum Clause {
    Tuple(Source),
    Relation(Source),
    Call(Call),
}

impl Clause {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Clause::Tuple(ref source) => {
                let relation = source.constrained_to(inputs, result);
                relation.into_iter().map(|tuple| Value::Tuple(tuple)).collect()
            },
            Clause::Relation(ref source) => {
                let relation = source.constrained_to(inputs, result);
                vec![Value::Relation(relation)]
            },
            Clause::Call(ref call) => {
                let value = call.eval(result).to_tuple().to_value();
                vec![value]
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct Query {
    pub clauses: Vec<Clause>,
}

// an iter over results of the query, where each result is either:
// * a `max_len` tuple indicating a valid result
// * a smaller tuple indicating a backtrack point
pub struct QueryIter<'a> {
    query: &'a Query,
    inputs: Vec<&'a Relation>,
    max_len: usize, // max length of a result
    now_len: usize, // ixes[0..now_len] and values[0..now_len] are all valid for the next result
    has_next: bool, // are there any more results to be found
    ixes: Vec<usize>, // index of the value last returned by each clause
    values: Vec<Vec<Value>>, // the constrained relations representing each clause
}

impl Query {
    pub fn iter<'a>(&'a self, inputs: Vec<&'a Relation>) -> QueryIter {
        let max_len = self.clauses.len();
        QueryIter{
            query: &self,
            inputs: inputs,
            max_len: max_len,
            now_len: 0,
            has_next: true, // can always return at least the early fail
            ixes: vec![0; max_len],
            values: vec![vec![]; max_len]
        }
    }
}

impl<'a> Iterator for QueryIter<'a> {
    type Item = Tuple;

    fn next(&mut self) -> Option<Tuple> {
        if !self.has_next { return None };

        let mut result = vec![];

        // set known values
        for i in (0 .. self.now_len) {
            result.push(self.values[i][self.ixes[i]].clone());
        }

        // determine the values that changed since last time
        for i in (self.now_len .. self.max_len) {
            let values = self.query.clauses[i].constrained_to(&self.inputs, &result);
            if values.len() == 0 {
                break;
            } else {
                self.now_len = i + 1;
                result.push(values[0].clone());
                self.values[i] = values;
                self.ixes[i] = 0;
            }
        }

        // see if there is a next result
        self.has_next = false;
        for i in (0 .. self.now_len).rev() {
            let ix = self.ixes[i] + 1;
            if ix < self.values[i].len() {
                self.ixes[i] = ix;
                self.has_next = true;
                self.now_len = i + 1;
                break;
            }
        }

        Some(result)
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None) // ie no hints
    }
}<|endoftext|>


<commit_before>use std::iter::IntoIterator;

use value::{Value, Tuple, Relation};
use interpreter;
use interpreter::{EveFn,Pattern};
use test::ToExpression; // TODO dont use test code in production!

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum ConstraintOp {
    LT,
    LTE,
    EQ,
    NEQ,
    GT,
    GTE,
}

#[derive(Clone, Debug)]
pub enum Ref {
    Constant{value: Value},
    Value{clause: usize, column: usize},
    Tuple{clause: usize},
    Relation{clause: usize},
}

impl Ref {
    fn resolve<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {

        match *self {
            Ref::Constant{ref value} => {
                value
            },
            Ref::Value{clause, column} => {
                match result[clause] {
                    Value::Tuple(ref tuple) => {
                        &tuple[column]
                    },
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Tuple{clause} => {
                let value = &result[clause];
                match *value {
                    Value::Tuple(..) => value,
                    _ => panic!("Expected a tuple"),
                }
            },
            Ref::Relation{clause} =>{
                let value = &result[clause];
                match *value {
                    Value::Relation(..) => value,
                    _ => panic!("Expected a relation"),
                }
            },
        }
    }
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub my_column: usize,
    pub op: ConstraintOp,
    pub other_ref: Ref,
}

impl Constraint {

    // Resolves the RHS reference in the constraint to a value
    fn prepare<'a>(&'a self, result: &'a Vec<Value>) -> &'a Value {
        self.other_ref.resolve(result)
    }

    // bearing in mind that Value is only PartialOrd so this may do weird things with NaN
    fn test(&self, my_row: &Vec<Value>, other_value: &Value) -> bool {
        let my_value = &my_row[self.my_column];
        match self.op {
            ConstraintOp::LT => my_value < other_value,
            ConstraintOp::LTE => my_value <= other_value,
            ConstraintOp::EQ => my_value == other_value,
            ConstraintOp::NEQ => my_value != other_value,
            ConstraintOp::GT => my_value > other_value,
            ConstraintOp::GTE => my_value >= other_value,
        }
    }
}

#[derive(Clone, Debug)]
pub struct Source {
    pub relation: usize,
    pub constraints: Vec<Constraint>,
}

impl Source {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Relation {

        let prepared: Vec<&Value> = self.constraints.iter()
                                                    .map(|constraint| constraint.prepare(result))
                                                    .collect();
        let input = inputs[self.relation];
        input.iter().filter(|row| self.constraints
                                      .iter()
                                      .zip(prepared.iter())
                                      .all(|(constraint, value)| constraint.test(row, value) ) )
                    .map(|row| row.clone())
                    .collect()
    }
}

#[derive(Clone,Debug)]
pub struct Call {
    pub fun: EveFn,
    pub args: CallArgs,
}

impl Call {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references and covert to an expression vector
        let args: Vec<interpreter::Expression> = self.args.iter()
                                                           .map(|arg_ref| arg_ref.resolve(result).to_expr())
                                                           .collect();

        let call = interpreter::Call{fun: self.fun.clone(), args: args};

        interpreter::evaluate(&interpreter::Expression::Call(call))
    }
}

#[derive(Clone,Debug)]
pub enum CallArg {
    Ref(Ref),
    Call(Call),
}

pub type CallArgs = Vec<CallArg>;

impl CallArg {
    fn resolve(&self, result: &Vec<Value>) -> Value {
        match self {
            &CallArg::Ref(ref arg_ref) => arg_ref.resolve(result).clone(),
            &CallArg::Call(ref arg_call) => arg_call.eval(result).clone(),
        }
    }
}

#[derive(Clone,Debug)]
pub struct Match {
    pub input: CallArg,
    pub patterns: Vec<Ref>,
    pub handlers: CallArgs,
}

impl Match {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references
        let input = self.input.resolve(result);
        let patterns: Vec<Pattern> = self.patterns.iter()
                                                  .map(|pattern| Pattern::Constant(pattern.resolve(result).clone()))
                                                  .collect();

        let handlers: Vec<interpreter::Expression> = self.handlers.iter()
                                                     .map(|handler| handler.resolve(result).to_expr())
                                                     .collect();

        // Build the interpreter match
        let evematch = interpreter::Match{input: input.to_expr(), patterns: patterns, handlers: handlers};

        interpreter::evaluate(&interpreter::Expression::Match(Box::new(evematch)))

    }
}

#[derive(Clone, Debug)]
pub enum Expression {
    Call(Call),
    Match(Match),
}

impl Expression {
    fn constrained_to(&self, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Expression::Call(ref call) => {
                let value = call.eval(result);
                vec![value]
            }
            Expression::Match(ref evematch) => {
                let value = evematch.eval(result);
                vec![value]
            }
        }
    }
}

#[derive(Clone, Debug)]
pub enum Clause {
    Tuple(Source),
    Relation(Source),
    Expression(Expression),
}

impl Clause {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Clause::Tuple(ref source) => {
                let relation = source.constrained_to(inputs, result);
                relation.into_iter().map(|tuple| Value::Tuple(tuple)).collect()
            }
            Clause::Relation(ref source) => {
                let relation = source.constrained_to(inputs, result);
                vec![Value::Relation(relation)]
            }
            Clause::Expression(ref expression) => {
                expression.constrained_to(result)
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct Query {
    pub clauses: Vec<Clause>,
}

// an iter over results of the query, where each result is either:
// * a `max_len` tuple indicating a valid result
// * a smaller tuple indicating a backtrack point
pub struct QueryIter<'a> {
    query: &'a Query,
    inputs: Vec<&'a Relation>,
    max_len: usize, // max length of a result
    now_len: usize, // ixes[0..now_len] and values[0..now_len] are all valid for the next result
    has_next: bool, // are there any more results to be found
    ixes: Vec<usize>, // index of the value last returned by each clause
    values: Vec<Vec<Value>>, // the constrained relations representing each clause
}

impl Query {
    pub fn iter<'a>(&'a self, inputs: Vec<&'a Relation>) -> QueryIter {
        let max_len = self.clauses.len();
        QueryIter{
            query: &self,
            inputs: inputs,
            max_len: max_len,
            now_len: 0,
            has_next: true, // can always return at least the early fail
            ixes: vec![0; max_len],
            values: vec![vec![]; max_len]
        }
    }
}

impl<'a> Iterator for QueryIter<'a> {
    type Item = Tuple;

    fn next(&mut self) -> Option<Tuple> {
        if !self.has_next { return None };

        let mut result = vec![];

        // set known values
        for i in (0 .. self.now_len) {
            result.push(self.values[i][self.ixes[i]].clone());
        }

        // determine the values that changed since last time
        for i in (self.now_len .. self.max_len) {
            let values = self.query.clauses[i].constrained_to(&self.inputs, &result);
            if values.len() == 0 {
                break;
            } else {
                self.now_len = i + 1;
                result.push(values[0].clone());
                self.values[i] = values;
                self.ixes[i] = 0;
            }
        }

        // see if there is a next result
        self.has_next = false;
        for i in (0 .. self.now_len).rev() {
            let ix = self.ixes[i] + 1;
            if ix < self.values[i].len() {
                self.ixes[i] = ix;
                self.has_next = true;
                self.now_len = i + 1;
                break;
            }
        }

        Some(result)
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None) // ie no hints
    }
}<commit_msg>Handle constraints where both side reference the same source<commit_after>use std::iter::IntoIterator;

use value::{Value, Tuple, Relation};
use interpreter;
use interpreter::{EveFn,Pattern};
use test::ToExpression; // TODO dont use test code in production!

#[derive(PartialEq, Eq, Clone, Debug)]
pub enum ConstraintOp {
    LT,
    LTE,
    EQ,
    NEQ,
    GT,
    GTE,
}

#[derive(Clone, Debug)]
pub enum Ref {
    Constant{value: Value},
    Value{clause: usize, column: usize},
    Tuple{clause: usize},
    Relation{clause: usize},
}

impl Ref {
    // TODO extra_row is a gross hack to handle constraints where both sides reference the same source
    fn resolve<'a>(&'a self, result: &'a Vec<Value>, extra_row: Option<&'a Vec<Value>>) -> &'a Value {
        match *self {
            Ref::Constant{ref value} => {
                value
            },
            Ref::Value{clause, column} => {
                if clause == result.len() {
                    &extra_row.unwrap()[column]
                } else {
                    match result[clause] {
                        Value::Tuple(ref tuple) => {
                            &tuple[column]
                        },
                        _ => panic!("Expected a tuple"),
                    }
                }
            },
            Ref::Tuple{clause} => {
                if clause == result.len() {
                    panic!("Can't refer to whole tuple of same source")
                } else {
                    let value = &result[clause];
                    match *value {
                        Value::Tuple(ref tuple) => {
                            value
                        },
                        _ => panic!("Expected a tuple"),
                    }
                }
            },
            Ref::Relation{clause} =>{
                if clause == result.len() {
                    panic!("Can't refer to whole relation of same source")
                } else {
                    let value = &result[clause];
                    match *value {
                        Value::Relation(ref relation) => {
                            value
                        },
                        _ => panic!("Expected a relation"),
                    }
                }
            },
        }
    }
}

#[derive(Clone, Debug)]
pub struct Constraint {
    pub my_column: usize,
    pub op: ConstraintOp,
    pub other_ref: Ref,
}

impl Constraint {
    // bearing in mind that Value is only PartialOrd so this may do weird things with NaN
    fn test(&self, result: &Vec<Value>, row: &Vec<Value>) -> bool {
        let my_value = &row[self.my_column];
        let other_value = self.other_ref.resolve(result, Some(row));
        match self.op {
            ConstraintOp::LT => my_value < other_value,
            ConstraintOp::LTE => my_value <= other_value,
            ConstraintOp::EQ => my_value == other_value,
            ConstraintOp::NEQ => my_value != other_value,
            ConstraintOp::GT => my_value > other_value,
            ConstraintOp::GTE => my_value >= other_value,
        }
    }
}

#[derive(Clone, Debug)]
pub struct Source {
    pub relation: usize,
    pub constraints: Vec<Constraint>,
}

impl Source {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Relation {
        let input = inputs[self.relation];
        input.iter().filter(|row| self.constraints
                                      .iter()
                                      .all(|constraint| constraint.test(result, row)))
                    .map(|row| row.clone())
                    .collect()
    }
}

#[derive(Clone,Debug)]
pub struct Call {
    pub fun: EveFn,
    pub args: CallArgs,
}

impl Call {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references and covert to an expression vector
        let args: Vec<interpreter::Expression> = self.args.iter()
                                                           .map(|arg_ref| arg_ref.resolve(result).to_expr())
                                                           .collect();

        let call = interpreter::Call{fun: self.fun.clone(), args: args};

        interpreter::evaluate(&interpreter::Expression::Call(call))
    }
}

#[derive(Clone,Debug)]
pub enum CallArg {
    Ref(Ref),
    Call(Call),
}

pub type CallArgs = Vec<CallArg>;

impl CallArg {
    fn resolve(&self, result: &Vec<Value>) -> Value {
        match self {
            &CallArg::Ref(ref arg_ref) => arg_ref.resolve(result, None).clone(),
            &CallArg::Call(ref arg_call) => arg_call.eval(result).clone(),
        }
    }
}

#[derive(Clone,Debug)]
pub struct Match {
    pub input: CallArg,
    pub patterns: Vec<Ref>,
    pub handlers: CallArgs,
}

impl Match {
    fn eval(&self, result: &Vec<Value>) -> Value {

        // Resolve references
        let input = self.input.resolve(result);
        let patterns: Vec<Pattern> = self.patterns.iter()
                                                  .map(|pattern| Pattern::Constant(pattern.resolve(result, None).clone()))
                                                  .collect();

        let handlers: Vec<interpreter::Expression> = self.handlers.iter()
                                                     .map(|handler| handler.resolve(result).to_expr())
                                                     .collect();

        // Build the interpreter match
        let evematch = interpreter::Match{input: input.to_expr(), patterns: patterns, handlers: handlers};

        interpreter::evaluate(&interpreter::Expression::Match(Box::new(evematch)))

    }
}

#[derive(Clone, Debug)]
pub enum Expression {
    Call(Call),
    Match(Match),
}

impl Expression {
    fn constrained_to(&self, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Expression::Call(ref call) => {
                let value = call.eval(result);
                vec![value]
            }
            Expression::Match(ref evematch) => {
                let value = evematch.eval(result);
                vec![value]
            }
        }
    }
}

#[derive(Clone, Debug)]
pub enum Clause {
    Tuple(Source),
    Relation(Source),
    Expression(Expression),
}

impl Clause {
    fn constrained_to(&self, inputs: &Vec<&Relation>, result: &Vec<Value>) -> Vec<Value> {
        match *self {
            Clause::Tuple(ref source) => {
                let relation = source.constrained_to(inputs, result);
                relation.into_iter().map(|tuple| Value::Tuple(tuple)).collect()
            }
            Clause::Relation(ref source) => {
                let relation = source.constrained_to(inputs, result);
                vec![Value::Relation(relation)]
            }
            Clause::Expression(ref expression) => {
                expression.constrained_to(result)
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct Query {
    pub clauses: Vec<Clause>,
}

// an iter over results of the query, where each result is either:
// * a `max_len` tuple indicating a valid result
// * a smaller tuple indicating a backtrack point
pub struct QueryIter<'a> {
    query: &'a Query,
    inputs: Vec<&'a Relation>,
    max_len: usize, // max length of a result
    now_len: usize, // ixes[0..now_len] and values[0..now_len] are all valid for the next result
    has_next: bool, // are there any more results to be found
    ixes: Vec<usize>, // index of the value last returned by each clause
    values: Vec<Vec<Value>>, // the constrained relations representing each clause
}

impl Query {
    pub fn iter<'a>(&'a self, inputs: Vec<&'a Relation>) -> QueryIter {
        let max_len = self.clauses.len();
        QueryIter{
            query: &self,
            inputs: inputs,
            max_len: max_len,
            now_len: 0,
            has_next: true, // can always return at least the early fail
            ixes: vec![0; max_len],
            values: vec![vec![]; max_len]
        }
    }
}

impl<'a> Iterator for QueryIter<'a> {
    type Item = Tuple;

    fn next(&mut self) -> Option<Tuple> {
        if !self.has_next { return None };

        let mut result = vec![];

        // set known values
        for i in (0 .. self.now_len) {
            result.push(self.values[i][self.ixes[i]].clone());
        }

        // determine the values that changed since last time
        for i in (self.now_len .. self.max_len) {
            let values = self.query.clauses[i].constrained_to(&self.inputs, &result);
            if values.len() == 0 {
                break;
            } else {
                self.now_len = i + 1;
                result.push(values[0].clone());
                self.values[i] = values;
                self.ixes[i] = 0;
            }
        }

        // see if there is a next result
        self.has_next = false;
        for i in (0 .. self.now_len).rev() {
            let ix = self.ixes[i] + 1;
            if ix < self.values[i].len() {
                self.ixes[i] = ix;
                self.has_next = true;
                self.now_len = i + 1;
                break;
            }
        }

        Some(result)
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None) // ie no hints
    }
}<|endoftext|>


<commit_before>use ffi;
#[cfg(feature = "use_glib")]
use glib::translate::*;
use libc::c_char;
use std::ffi::{CStr, CString};
#[cfg(not(feature = "use_glib"))]
use std::ptr;

use enums::{FontSlant, FontType, FontWeight};

#[cfg(any(feature = "freetype", feature = "dox"))]
use enums::FtSynthesize;

use utils::status_to_result;

#[cfg(feature = "use_glib")]
glib_wrapper! {
    #[derive(Debug)]
    pub struct FontFace(Shared<ffi::cairo_font_face_t>);

    match fn {
        ref => |ptr| ffi::cairo_font_face_reference(ptr),
        unref => |ptr| ffi::cairo_font_face_destroy(ptr),
        get_type => || ffi::gobject::cairo_gobject_font_face_get_type(),
    }
}

#[cfg(not(feature = "use_glib"))]
#[derive(Debug)]
pub struct FontFace(ptr::NonNull<ffi::cairo_font_face_t>);

impl FontFace {
    pub fn toy_create(family: &str, slant: FontSlant, weight: FontWeight) -> FontFace {
        let font_face: FontFace = unsafe {
            let family = CString::new(family).unwrap();
            FontFace::from_raw_full(ffi::cairo_toy_font_face_create(
                family.as_ptr(),
                slant.into(),
                weight.into(),
            ))
        };
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    // Safety: the FT_Face must be valid and not be freed until the `FontFace` is dropped.
    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub unsafe fn create_from_ft(face: ffi::FT_Face) -> FontFace {
        FontFace::from_raw_full(ffi::cairo_ft_font_face_create_for_ft_face(face, 0))
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_full(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_none(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.to_glib_none().0
    }

    #[cfg(not(feature = "use_glib"))]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.0.as_ptr()
    }

    pub fn toy_get_family(&self) -> Option<String> {
        unsafe { to_optional_string(ffi::cairo_toy_font_face_get_family(self.to_raw_none())) }
    }

    pub fn toy_get_slant(&self) -> FontSlant {
        unsafe { FontSlant::from(ffi::cairo_toy_font_face_get_slant(self.to_raw_none())) }
    }

    pub fn toy_get_weight(&self) -> FontWeight {
        unsafe { FontWeight::from(ffi::cairo_toy_font_face_get_weight(self.to_raw_none())) }
    }

    pub fn get_type(&self) -> FontType {
        unsafe { FontType::from(ffi::cairo_font_face_get_type(self.to_raw_none())) }
    }

    pub fn get_reference_count(&self) -> usize {
        unsafe { ffi::cairo_font_face_get_reference_count(self.to_raw_none()) as usize }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn get_synthesize(&self) -> FtSynthesize {
        unsafe { FtSynthesize::from(ffi::cairo_ft_font_face_get_synthesize(self.to_raw_none())) }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn set_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_set_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn unset_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_unset_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    user_data_methods! {
        ffi::cairo_font_face_get_user_data,
        ffi::cairo_font_face_set_user_data,
    }
}

#[cfg(not(feature = "use_glib"))]
impl Drop for FontFace {
    fn drop(&mut self) {
        unsafe {
            ffi::cairo_font_face_destroy(self.to_raw_none());
        }
    }
}

#[cfg(not(feature = "use_glib"))]
impl Clone for FontFace {
    fn clone(&self) -> FontFace {
        unsafe { FontFace::from_raw_none(self.to_raw_none()) }
    }
}

pub(crate) unsafe fn to_optional_string(str: *const c_char) -> Option<String> {
    if str.is_null() {
        None
    } else {
        Some(String::from_utf8_lossy(CStr::from_ptr(str).to_bytes()).into_owned())
    }
}
<commit_msg>Remove higher-level function.<commit_after>use ffi;
#[cfg(feature = "use_glib")]
use glib::translate::*;
use libc::c_char;
use std::ffi::{CStr, CString};
#[cfg(not(feature = "use_glib"))]
use std::ptr;

use enums::{FontSlant, FontType, FontWeight};

#[cfg(any(feature = "freetype", feature = "dox"))]
use enums::FtSynthesize;

use utils::status_to_result;

#[cfg(feature = "use_glib")]
glib_wrapper! {
    #[derive(Debug)]
    pub struct FontFace(Shared<ffi::cairo_font_face_t>);

    match fn {
        ref => |ptr| ffi::cairo_font_face_reference(ptr),
        unref => |ptr| ffi::cairo_font_face_destroy(ptr),
        get_type => || ffi::gobject::cairo_gobject_font_face_get_type(),
    }
}

#[cfg(not(feature = "use_glib"))]
#[derive(Debug)]
pub struct FontFace(ptr::NonNull<ffi::cairo_font_face_t>);

impl FontFace {
    pub fn toy_create(family: &str, slant: FontSlant, weight: FontWeight) -> FontFace {
        let font_face: FontFace = unsafe {
            let family = CString::new(family).unwrap();
            FontFace::from_raw_full(ffi::cairo_toy_font_face_create(
                family.as_ptr(),
                slant.into(),
                weight.into(),
            ))
        };
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_full(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_none(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.to_glib_none().0
    }

    #[cfg(not(feature = "use_glib"))]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.0.as_ptr()
    }

    pub fn toy_get_family(&self) -> Option<String> {
        unsafe { to_optional_string(ffi::cairo_toy_font_face_get_family(self.to_raw_none())) }
    }

    pub fn toy_get_slant(&self) -> FontSlant {
        unsafe { FontSlant::from(ffi::cairo_toy_font_face_get_slant(self.to_raw_none())) }
    }

    pub fn toy_get_weight(&self) -> FontWeight {
        unsafe { FontWeight::from(ffi::cairo_toy_font_face_get_weight(self.to_raw_none())) }
    }

    pub fn get_type(&self) -> FontType {
        unsafe { FontType::from(ffi::cairo_font_face_get_type(self.to_raw_none())) }
    }

    pub fn get_reference_count(&self) -> usize {
        unsafe { ffi::cairo_font_face_get_reference_count(self.to_raw_none()) as usize }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn get_synthesize(&self) -> FtSynthesize {
        unsafe { FtSynthesize::from(ffi::cairo_ft_font_face_get_synthesize(self.to_raw_none())) }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn set_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_set_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    #[cfg(any(feature = "freetype", feature = "dox"))]
    pub fn unset_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_unset_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    user_data_methods! {
        ffi::cairo_font_face_get_user_data,
        ffi::cairo_font_face_set_user_data,
    }
}

#[cfg(not(feature = "use_glib"))]
impl Drop for FontFace {
    fn drop(&mut self) {
        unsafe {
            ffi::cairo_font_face_destroy(self.to_raw_none());
        }
    }
}

#[cfg(not(feature = "use_glib"))]
impl Clone for FontFace {
    fn clone(&self) -> FontFace {
        unsafe { FontFace::from_raw_none(self.to_raw_none()) }
    }
}

pub(crate) unsafe fn to_optional_string(str: *const c_char) -> Option<String> {
    if str.is_null() {
        None
    } else {
        Some(String::from_utf8_lossy(CStr::from_ptr(str).to_bytes()).into_owned())
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Div, Mul, Rem, Sub};
use typedef::*;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum Value {
    Boolean(bool),
    Float(Float),
    Integer(Integer),
    Symbol(String),
    String(String),
    Nil,
}

impl Value {
    pub fn is_nil(&self) -> bool {
        match self {
            &Value::Nil => true,
            _ => false,
        }
    }
}

impl Add for Value {
    type Output = Value;

    fn add(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float + rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float + (rhs_integer as Float)),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_float, rhs_string),),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) + rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer + rhs_integer),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_integer, rhs_string),),
                    _ => Value::Nil,
                }
            }

            Value::String(lhs_string) => {
                match rhs {
                    Value::Float(rhs_float) => Value::String(format!("{}{}", lhs_string, rhs_float),),
                    Value::Integer(rhs_integer) => Value::String(format!("{}{}", lhs_string, rhs_integer),),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_string, rhs_string),),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Sub for Value {
    type Output = Value;

    fn sub(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float - rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float - (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) - rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer - rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Mul for Value {
    type Output = Value;

    fn mul(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float * rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float * (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) * rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer * rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Div for Value {
    type Output = Value;

    fn div(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float / rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float / (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) / rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer / rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Rem for Value {
    type Output = Value;

    fn rem(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float % rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float % (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) % rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer % rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Target {
    Register(usize),
    Stack(usize),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Instruction {
    Add(Target, Target),
    Sub(Target, Target),
    Div(Target, Target),
    Mul(Target, Target),
    Mod(Target, Target),

    Cmp(Target, Target),
    Jmp(Address),
    JmpLt(Address),
    JmpGt(Address),
    JmpEq(Address),

    Push(Target, Value),
    Mov(Target, Target),
    Swp(Target, Target),

    Call(Address),
    Ret,

    Halt,
}

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Program {
    pub preamble: String,
    pub version: String,
    pub instructions: Vec<Instruction>,
}

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

    #[test]
    fn comparison() {
        assert!(Value::Float(1.3) < Value::Float(1.4));
        assert!(Value::Float(3.1) > Value::Float(2.4));
        assert!(Value::Float(9.6) == Value::Float(9.6));

        assert!(Value::Integer(124) < Value::Integer(234));
        assert!(Value::Integer(4) > Value::Integer(1));
        assert!(Value::Integer(839) == Value::Integer(839));
    }
}
<commit_msg>Added char primitive<commit_after>use std::ops::{Add, Div, Mul, Rem, Sub};
use typedef::*;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum Value {
    Boolean(bool),
    Float(Float),
    Integer(Integer),
    Symbol(String),
    String(String),
    Char(char),
    Nil,
}

impl Value {
    pub fn is_nil(&self) -> bool {
        match self {
            &Value::Nil => true,
            _ => false,
        }
    }
}

impl Add for Value {
    type Output = Value;

    fn add(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float + rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float + (rhs_integer as Float)),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_float, rhs_string),),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) + rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer + rhs_integer),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_integer, rhs_string),),
                    _ => Value::Nil,
                }
            }

            Value::String(lhs_string) => {
                match rhs {
                    Value::Float(rhs_float) => Value::String(format!("{}{}", lhs_string, rhs_float),),
                    Value::Integer(rhs_integer) => Value::String(format!("{}{}", lhs_string, rhs_integer),),
                    Value::String(rhs_string) => Value::String(format!("{}{}", lhs_string, rhs_string),),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Sub for Value {
    type Output = Value;

    fn sub(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float - rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float - (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) - rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer - rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Mul for Value {
    type Output = Value;

    fn mul(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float * rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float * (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) * rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer * rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Div for Value {
    type Output = Value;

    fn div(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float / rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float / (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) / rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer / rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

impl Rem for Value {
    type Output = Value;

    fn rem(self, rhs: Self) -> Self::Output {
        match self {
            Value::Float(lhs_float) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float(lhs_float % rhs_float),
                    Value::Integer(rhs_integer) => Value::Float(lhs_float % (rhs_integer as Float)),
                    _ => Value::Nil,
                }
            }

            Value::Integer(lhs_integer) => {
                match rhs {
                    Value::Float(rhs_float) => Value::Float((lhs_integer as Float) % rhs_float),
                    Value::Integer(rhs_integer) => Value::Integer(lhs_integer % rhs_integer),
                    _ => Value::Nil,
                }
            }
            _ => Value::Nil,
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Target {
    Register(usize),
    Stack(usize),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Instruction {
    Add(Target, Target),
    Sub(Target, Target),
    Div(Target, Target),
    Mul(Target, Target),
    Mod(Target, Target),

    Cmp(Target, Target),
    Jmp(Address),
    JmpLt(Address),
    JmpGt(Address),
    JmpEq(Address),

    Push(Target, Value),
    Mov(Target, Target),
    Swp(Target, Target),

    Call(Address),
    Ret,

    Halt,
}

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Program {
    pub preamble: String,
    pub version: String,
    pub instructions: Vec<Instruction>,
}

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

    #[test]
    fn comparison() {
        assert!(Value::Float(1.3) < Value::Float(1.4));
        assert!(Value::Float(3.1) > Value::Float(2.4));
        assert!(Value::Float(9.6) == Value::Float(9.6));

        assert!(Value::Integer(124) < Value::Integer(234));
        assert!(Value::Integer(4) > Value::Integer(1));
        assert!(Value::Integer(839) == Value::Integer(839));
    }
}
<|endoftext|>