<commit_before>//! A private parser implementation of IPv4, IPv6, and socket addresses.
//!
//! This module is "publicly exported" through the `FromStr` implementations
//! below.

#[cfg(test)]
mod tests;

use crate::convert::TryInto as _;
use crate::error::Error;
use crate::fmt;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use crate::str::FromStr;

trait ReadNumberHelper: crate::marker::Sized {
    const ZERO: Self;
    fn checked_mul(&self, other: u32) -> Option<Self>;
    fn checked_add(&self, other: u32) -> Option<Self>;
}

macro_rules! impl_helper {
    ($($t:ty)*) => ($(impl ReadNumberHelper for $t {
        const ZERO: Self = 0;
        #[inline]
        fn checked_mul(&self, other: u32) -> Option<Self> {
            Self::checked_mul(*self, other.try_into().ok()?)
        }
        #[inline]
        fn checked_add(&self, other: u32) -> Option<Self> {
            Self::checked_add(*self, other.try_into().ok()?)
        }
    })*)
}

impl_helper! { u8 u16 u32 }

struct Parser<'a> {
    // Parsing as ASCII, so can use byte array.
    state: &'a [u8],
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser { state: input.as_bytes() }
    }

    /// Run a parser, and restore the pre-parse state if it fails.
    fn read_atomically<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let state = self.state;
        let result = inner(self);
        if result.is_none() {
            self.state = state;
        }
        result
    }

    /// Run a parser, but fail if the entire input wasn't consumed.
    /// Doesn't run atomically.
    fn parse_with<T, F>(&mut self, inner: F) -> Result<T, AddrParseError>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let result = inner(self);
        if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(()))
    }

    /// Peek the next character from the input
    fn peek_char(&self) -> Option<char> {
        self.state.first().map(|&b| char::from(b))
    }

    /// Read the next character from the input
    fn read_char(&mut self) -> Option<char> {
        self.state.split_first().map(|(&b, tail)| {
            self.state = tail;
            char::from(b)
        })
    }

    #[must_use]
    /// Read the next character from the input if it matches the target.
    fn read_given_char(&mut self, target: char) -> Option<()> {
        self.read_atomically(|p| {
            p.read_char().and_then(|c| if c == target { Some(()) } else { None })
        })
    }

    /// Helper for reading separators in an indexed loop. Reads the separator
    /// character iff index > 0, then runs the parser. When used in a loop,
    /// the separator character will only be read on index > 0 (see
    /// read_ipv4_addr for an example)
    fn read_separator<T, F>(&mut self, sep: char, index: usize, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_atomically(move |p| {
            if index > 0 {
                p.read_given_char(sep)?;
            }
            inner(p)
        })
    }

    // Read a number off the front of the input in the given radix, stopping
    // at the first non-digit character or eof. Fails if the number has more
    // digits than max_digits or if there is no number.
    fn read_number<T: ReadNumberHelper>(
        &mut self,
        radix: u32,
        max_digits: Option<usize>,
        allow_zero_prefix: bool,
    ) -> Option<T> {
        self.read_atomically(move |p| {
            let mut result = T::ZERO;
            let mut digit_count = 0;
            let has_leading_zero = p.peek_char() == Some('0');

            while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                result = result.checked_mul(radix)?;
                result = result.checked_add(digit)?;
                digit_count += 1;
                if let Some(max_digits) = max_digits {
                    if digit_count > max_digits {
                        return None;
                    }
                }
            }

            if digit_count == 0 {
                None
            } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
                None
            } else {
                Some(result)
            }
        })
    }

    /// Read an IPv4 address.
    fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
        self.read_atomically(|p| {
            let mut groups = [0; 4];

            for (i, slot) in groups.iter_mut().enumerate() {
                *slot = p.read_separator('.', i, |p| {
                    // Disallow octal number in IP string.
                    // https://tools.ietf.org/html/rfc6943#section-3.1.1
                    p.read_number(10, None, false)
                })?;
            }

            Some(groups.into())
        })
    }

    /// Read an IPv6 Address.
    fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
        /// Read a chunk of an IPv6 address into `groups`. Returns the number
        /// of groups read, along with a bool indicating if an embedded
        /// trailing IPv4 address was read. Specifically, read a series of
        /// colon-separated IPv6 groups (0x0000 - 0xFFFF), with an optional
        /// trailing embedded IPv4 address.
        fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) {
            let limit = groups.len();

            for (i, slot) in groups.iter_mut().enumerate() {
                // Try to read a trailing embedded IPv4 address. There must be
                // at least two groups left.
                if i < limit - 1 {
                    let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr());

                    if let Some(v4_addr) = ipv4 {
                        let [one, two, three, four] = v4_addr.octets();
                        groups[i + 0] = u16::from_be_bytes([one, two]);
                        groups[i + 1] = u16::from_be_bytes([three, four]);
                        return (i + 2, true);
                    }
                }

                let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true));

                match group {
                    Some(g) => *slot = g,
                    None => return (i, false),
                }
            }
            (groups.len(), false)
        }

        self.read_atomically(|p| {
            // Read the front part of the address; either the whole thing, or up
            // to the first ::
            let mut head = [0; 8];
            let (head_size, head_ipv4) = read_groups(p, &mut head);

            if head_size == 8 {
                return Some(head.into());
            }

            // IPv4 part is not allowed before `::`
            if head_ipv4 {
                return None;
            }

            // Read `::` if previous code parsed less than 8 groups.
            // `::` indicates one or more groups of 16 bits of zeros.
            p.read_given_char(':')?;
            p.read_given_char(':')?;

            // Read the back part of the address. The :: must contain at least one
            // set of zeroes, so our max length is 7.
            let mut tail = [0; 7];
            let limit = 8 - (head_size + 1);
            let (tail_size, _) = read_groups(p, &mut tail[..limit]);

            // Concat the head and tail of the IP address
            head[(8 - tail_size)..8].copy_from_slice(&tail[..tail_size]);

            Some(head.into())
        })
    }

    /// Read an IP Address, either IPv4 or IPv6.
    fn read_ip_addr(&mut self) -> Option<IpAddr> {
        self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6))
    }

    /// Read a `:` followed by a port in base 10.
    fn read_port(&mut self) -> Option<u16> {
        self.read_atomically(|p| {
            p.read_given_char(':')?;
            p.read_number(10, None, true)
        })
    }

    /// Read a `%` followed by a scope ID in base 10.
    fn read_scope_id(&mut self) -> Option<u32> {
        self.read_atomically(|p| {
            p.read_given_char('%')?;
            p.read_number(10, None, true)
        })
    }

    /// Read an IPv4 address with a port.
    fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
        self.read_atomically(|p| {
            let ip = p.read_ipv4_addr()?;
            let port = p.read_port()?;
            Some(SocketAddrV4::new(ip, port))
        })
    }

    /// Read an IPv6 address with a port.
    fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
        self.read_atomically(|p| {
            p.read_given_char('[')?;
            let ip = p.read_ipv6_addr()?;
            let scope_id = p.read_scope_id().unwrap_or(0);
            p.read_given_char(']')?;

            let port = p.read_port()?;
            Some(SocketAddrV6::new(ip, port, 0, scope_id))
        })
    }

    /// Read an IP address with a port
    fn read_socket_addr(&mut self) -> Option<SocketAddr> {
        self.read_socket_addr_v4()
            .map(SocketAddr::V4)
            .or_else(|| self.read_socket_addr_v6().map(SocketAddr::V6))
    }
}

#[stable(feature = "ip_addr", since = "1.7.0")]
impl FromStr for IpAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ip_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv4Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
        // don't try to parse if too long
        if s.len() > 15 {
            Err(AddrParseError(()))
        } else {
            Parser::new(s).parse_with(|p| p.read_ipv4_addr())
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv6Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv6_addr())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV4 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v4())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV6 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v6())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for SocketAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr())
    }
}

/// An error which can be returned when parsing an IP address or a socket address.
///
/// This error is used as the error type for the [`FromStr`] implementation for
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
/// [`SocketAddrV6`].
///
/// # Potential causes
///
/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
/// often because it includes information only handled by a different address type.
///
/// ```should_panic
/// use std::net::IpAddr;
/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
/// ```
///
/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
///
/// ```
/// use std::net::SocketAddr;
///
/// // No problem, the `panic!` message has disappeared.
/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddrParseError(());

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl fmt::Display for AddrParseError {
    #[allow(deprecated, deprecated_in_future)]
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl Error for AddrParseError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "invalid IP address syntax"
    }
}
<commit_msg>Specify maximum IP address length<commit_after>//! A private parser implementation of IPv4, IPv6, and socket addresses.
//!
//! This module is "publicly exported" through the `FromStr` implementations
//! below.

#[cfg(test)]
mod tests;

use crate::convert::TryInto as _;
use crate::error::Error;
use crate::fmt;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use crate::str::FromStr;

trait ReadNumberHelper: crate::marker::Sized {
    const ZERO: Self;
    fn checked_mul(&self, other: u32) -> Option<Self>;
    fn checked_add(&self, other: u32) -> Option<Self>;
}

macro_rules! impl_helper {
    ($($t:ty)*) => ($(impl ReadNumberHelper for $t {
        const ZERO: Self = 0;
        #[inline]
        fn checked_mul(&self, other: u32) -> Option<Self> {
            Self::checked_mul(*self, other.try_into().ok()?)
        }
        #[inline]
        fn checked_add(&self, other: u32) -> Option<Self> {
            Self::checked_add(*self, other.try_into().ok()?)
        }
    })*)
}

impl_helper! { u8 u16 u32 }

struct Parser<'a> {
    // Parsing as ASCII, so can use byte array.
    state: &'a [u8],
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser { state: input.as_bytes() }
    }

    /// Run a parser, and restore the pre-parse state if it fails.
    fn read_atomically<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let state = self.state;
        let result = inner(self);
        if result.is_none() {
            self.state = state;
        }
        result
    }

    /// Run a parser, but fail if the entire input wasn't consumed.
    /// Doesn't run atomically.
    fn parse_with<T, F>(&mut self, inner: F) -> Result<T, AddrParseError>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let result = inner(self);
        if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(()))
    }

    /// Peek the next character from the input
    fn peek_char(&self) -> Option<char> {
        self.state.first().map(|&b| char::from(b))
    }

    /// Read the next character from the input
    fn read_char(&mut self) -> Option<char> {
        self.state.split_first().map(|(&b, tail)| {
            self.state = tail;
            char::from(b)
        })
    }

    #[must_use]
    /// Read the next character from the input if it matches the target.
    fn read_given_char(&mut self, target: char) -> Option<()> {
        self.read_atomically(|p| {
            p.read_char().and_then(|c| if c == target { Some(()) } else { None })
        })
    }

    /// Helper for reading separators in an indexed loop. Reads the separator
    /// character iff index > 0, then runs the parser. When used in a loop,
    /// the separator character will only be read on index > 0 (see
    /// read_ipv4_addr for an example)
    fn read_separator<T, F>(&mut self, sep: char, index: usize, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_atomically(move |p| {
            if index > 0 {
                p.read_given_char(sep)?;
            }
            inner(p)
        })
    }

    // Read a number off the front of the input in the given radix, stopping
    // at the first non-digit character or eof. Fails if the number has more
    // digits than max_digits or if there is no number.
    fn read_number<T: ReadNumberHelper>(
        &mut self,
        radix: u32,
        max_digits: Option<usize>,
        allow_zero_prefix: bool,
    ) -> Option<T> {
        self.read_atomically(move |p| {
            let mut result = T::ZERO;
            let mut digit_count = 0;
            let has_leading_zero = p.peek_char() == Some('0');

            while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                result = result.checked_mul(radix)?;
                result = result.checked_add(digit)?;
                digit_count += 1;
                if let Some(max_digits) = max_digits {
                    if digit_count > max_digits {
                        return None;
                    }
                }
            }

            if digit_count == 0 {
                None
            } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
                None
            } else {
                Some(result)
            }
        })
    }

    /// Read an IPv4 address.
    fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
        self.read_atomically(|p| {
            let mut groups = [0; 4];

            for (i, slot) in groups.iter_mut().enumerate() {
                *slot = p.read_separator('.', i, |p| {
                    // Disallow octal number in IP string.
                    // https://tools.ietf.org/html/rfc6943#section-3.1.1
                    p.read_number(10, Some(3), false)
                })?;
            }

            Some(groups.into())
        })
    }

    /// Read an IPv6 Address.
    fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
        /// Read a chunk of an IPv6 address into `groups`. Returns the number
        /// of groups read, along with a bool indicating if an embedded
        /// trailing IPv4 address was read. Specifically, read a series of
        /// colon-separated IPv6 groups (0x0000 - 0xFFFF), with an optional
        /// trailing embedded IPv4 address.
        fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) {
            let limit = groups.len();

            for (i, slot) in groups.iter_mut().enumerate() {
                // Try to read a trailing embedded IPv4 address. There must be
                // at least two groups left.
                if i < limit - 1 {
                    let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr());

                    if let Some(v4_addr) = ipv4 {
                        let [one, two, three, four] = v4_addr.octets();
                        groups[i + 0] = u16::from_be_bytes([one, two]);
                        groups[i + 1] = u16::from_be_bytes([three, four]);
                        return (i + 2, true);
                    }
                }

                let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true));

                match group {
                    Some(g) => *slot = g,
                    None => return (i, false),
                }
            }
            (groups.len(), false)
        }

        self.read_atomically(|p| {
            // Read the front part of the address; either the whole thing, or up
            // to the first ::
            let mut head = [0; 8];
            let (head_size, head_ipv4) = read_groups(p, &mut head);

            if head_size == 8 {
                return Some(head.into());
            }

            // IPv4 part is not allowed before `::`
            if head_ipv4 {
                return None;
            }

            // Read `::` if previous code parsed less than 8 groups.
            // `::` indicates one or more groups of 16 bits of zeros.
            p.read_given_char(':')?;
            p.read_given_char(':')?;

            // Read the back part of the address. The :: must contain at least one
            // set of zeroes, so our max length is 7.
            let mut tail = [0; 7];
            let limit = 8 - (head_size + 1);
            let (tail_size, _) = read_groups(p, &mut tail[..limit]);

            // Concat the head and tail of the IP address
            head[(8 - tail_size)..8].copy_from_slice(&tail[..tail_size]);

            Some(head.into())
        })
    }

    /// Read an IP Address, either IPv4 or IPv6.
    fn read_ip_addr(&mut self) -> Option<IpAddr> {
        self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6))
    }

    /// Read a `:` followed by a port in base 10.
    fn read_port(&mut self) -> Option<u16> {
        self.read_atomically(|p| {
            p.read_given_char(':')?;
            p.read_number(10, None, true)
        })
    }

    /// Read a `%` followed by a scope ID in base 10.
    fn read_scope_id(&mut self) -> Option<u32> {
        self.read_atomically(|p| {
            p.read_given_char('%')?;
            p.read_number(10, None, true)
        })
    }

    /// Read an IPv4 address with a port.
    fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
        self.read_atomically(|p| {
            let ip = p.read_ipv4_addr()?;
            let port = p.read_port()?;
            Some(SocketAddrV4::new(ip, port))
        })
    }

    /// Read an IPv6 address with a port.
    fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
        self.read_atomically(|p| {
            p.read_given_char('[')?;
            let ip = p.read_ipv6_addr()?;
            let scope_id = p.read_scope_id().unwrap_or(0);
            p.read_given_char(']')?;

            let port = p.read_port()?;
            Some(SocketAddrV6::new(ip, port, 0, scope_id))
        })
    }

    /// Read an IP address with a port
    fn read_socket_addr(&mut self) -> Option<SocketAddr> {
        self.read_socket_addr_v4()
            .map(SocketAddr::V4)
            .or_else(|| self.read_socket_addr_v6().map(SocketAddr::V6))
    }
}

#[stable(feature = "ip_addr", since = "1.7.0")]
impl FromStr for IpAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ip_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv4Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
        // don't try to parse if too long
        if s.len() > 15 {
            Err(AddrParseError(()))
        } else {
            Parser::new(s).parse_with(|p| p.read_ipv4_addr())
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv6Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv6_addr())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV4 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v4())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV6 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v6())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for SocketAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr())
    }
}

/// An error which can be returned when parsing an IP address or a socket address.
///
/// This error is used as the error type for the [`FromStr`] implementation for
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
/// [`SocketAddrV6`].
///
/// # Potential causes
///
/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
/// often because it includes information only handled by a different address type.
///
/// ```should_panic
/// use std::net::IpAddr;
/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
/// ```
///
/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
///
/// ```
/// use std::net::SocketAddr;
///
/// // No problem, the `panic!` message has disappeared.
/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddrParseError(());

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl fmt::Display for AddrParseError {
    #[allow(deprecated, deprecated_in_future)]
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl Error for AddrParseError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "invalid IP address syntax"
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use crate::{action_plugins::stratagem::server, agent_error::ImlAgentError};
use futures::{future::IntoFuture, Future};
use iml_wire_types::{ActionName, ToJsonValue};
use std::collections::HashMap;

type BoxedFuture = Box<
    Future<Item = std::result::Result<serde_json::value::Value, String>, Error = ()>
        + 'static
        + Send,
>;

type Callback = Box<Fn(serde_json::value::Value) -> BoxedFuture + Send + Sync>;

fn mk_boxed_future<T: 'static, F: 'static, R, Fut: 'static>(
    v: serde_json::value::Value,
    f: F,
) -> BoxedFuture
where
    T: serde::de::DeserializeOwned + Send,
    R: serde::Serialize + 'static + Send,
    F: Fn(T) -> Fut + Send,
    Fut: Future<Item = R, Error = ImlAgentError> + Send,
{
    Box::new(
        serde_json::from_value(v)
            .into_future()
            .from_err()
            .and_then(f)
            .then(|x| {
                Ok(match x {
                    Ok(x) => x.to_json_value(),
                    Err(e) => Err(format!("{}", e)),
                })
            }),
    ) as BoxedFuture
}

fn mk_callback<Fut: 'static, F: 'static, T: 'static, R: 'static>(f: &'static F) -> Callback
where
    Fut: Future<Item = R, Error = ImlAgentError> + Send,
    F: Fn(T) -> Fut + Send + Sync,
    T: serde::de::DeserializeOwned + Send,
    R: serde::Serialize + Send,
{
    Box::new(move |v| mk_boxed_future(v, f))
}

pub type Actions = HashMap<ActionName, Callback>;

/// The registry of available actions to the `AgentDaemon`.
/// Add new Actions to the fn body as they are created.
pub fn create_registry() -> HashMap<ActionName, Callback> {
    let mut map = HashMap::new();

    map.insert(
        "start_scan_stratagem".into(),
        mk_callback(&server::trigger_scan),
    );

    map.insert(
        "stream_fidlists_stratagem".into(),
        mk_callback(&server::stream_fidlists),
    );

    log::info!("Loaded the following ActionPlugins:");

    for ActionName(key) in map.keys() {
        log::info!("{}", key)
    }

    map
}
<commit_msg>Simplify plugin types (#995)<commit_after>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use crate::{action_plugins::stratagem::server, agent_error::ImlAgentError};
use futures::{future::IntoFuture, Future};
use iml_wire_types::{ActionName, ToJsonValue};
use std::collections::HashMap;

type BoxedFuture = Box<
    Future<Item = std::result::Result<serde_json::value::Value, String>, Error = ()>
        + 'static
        + Send,
>;

type Callback = Box<Fn(serde_json::value::Value) -> BoxedFuture + Send + Sync>;

fn mk_boxed_future<T, R, Fut>(v: serde_json::value::Value, f: fn(T) -> Fut) -> BoxedFuture
where
    T: serde::de::DeserializeOwned + Send + 'static,
    R: serde::Serialize + 'static + Send,
    Fut: Future<Item = R, Error = ImlAgentError> + Send + 'static,
{
    Box::new(
        serde_json::from_value(v)
            .into_future()
            .from_err()
            .and_then(f)
            .then(|x| {
                Ok(match x {
                    Ok(x) => x.to_json_value(),
                    Err(e) => Err(format!("{}", e)),
                })
            }),
    ) as BoxedFuture
}

fn mk_callback<Fut, T, R>(f: fn(T) -> Fut) -> Callback
where
    Fut: Future<Item = R, Error = ImlAgentError> + Send + 'static,
    T: serde::de::DeserializeOwned + Send + 'static,
    R: serde::Serialize + Send + 'static,
{
    Box::new(move |v| mk_boxed_future(v, f))
}

pub type Actions = HashMap<ActionName, Callback>;

/// The registry of available actions to the `AgentDaemon`.
/// Add new Actions to the fn body as they are created.
pub fn create_registry() -> HashMap<ActionName, Callback> {
    let mut map = HashMap::new();

    map.insert(
        "start_scan_stratagem".into(),
        mk_callback(server::trigger_scan),
    );

    map.insert(
        "stream_fidlists_stratagem".into(),
        mk_callback(server::stream_fidlists),
    );

    log::info!("Loaded the following ActionPlugins:");

    for ActionName(key) in map.keys() {
        log::info!("{}", key)
    }

    map
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use io::{IoResult, File};
    use path::Path;
    use rand::Rng;
    use rand::reader::ReaderRng;
    use result::{Ok, Err};
    use slice::SlicePrelude;
    use mem;
    use os::errno;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(target_arch = "arm")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(v[mut read..]);
            if result == -1 {
                let err = errno() as libc::c_int;
                if err == libc::EINTR {
                    continue;
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as uint;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8, ..4] = [0u8, ..4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8, ..8] = [0u8, ..8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn is_getrandom_available() -> bool {
        use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed};

        static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL;
        static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL;

        if !GETRANDOM_CHECKED.load(Relaxed) {
            let mut buf: [u8, ..0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = errno() as libc::c_int;
                err != libc::ENOSYS
            } else {
                true
            };
            GETRANDOM_AVAILABLE.store(available, Relaxed);
            GETRANDOM_CHECKED.store(true, Relaxed);
            available
        } else {
            GETRANDOM_AVAILABLE.load(Relaxed)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReaderRng(ReaderRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open(&Path::new("/dev/urandom")));
            let reader_rng = ReaderRng::new(reader);

            Ok(OsRng { inner: OsReaderRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReaderRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReaderRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReaderRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use io::{IoResult};
    use kinds::marker;
    use mem;
    use os;
    use rand::Rng;
    use result::{Ok};
    use self::libc::{c_int, size_t};
    use slice::{SlicePrelude};

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        marker: marker::NoCopy
    }

    #[repr(C)]
    struct SecRandom;

    #[allow(non_upper_case_globals)]
    static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            Ok(OsRng {marker: marker::NoCopy} )
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use io::{IoResult, IoError};
    use mem;
    use ops::Drop;
    use os;
    use rand::Rng;
    use result::{Ok, Err};
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};
    use slice::{SlicePrelude};

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    static PROV_RSA_FULL: DWORD = 1;
    static CRYPT_SILENT: DWORD = 64;
    static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(IoError::last_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}", os::last_os_error());
            }
        }
    }
}

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

    use super::OsRng;
    use rand::Rng;
    use task;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8, .. 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in range(0u, 20) {
            let (tx, rx) = channel();
            txs.push(tx);
            task::spawn(proc() {
                // wait until all the tasks are ready to go.
                rx.recv();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                task::deschedule();
                let mut v = [0u8, .. 1000];

                for _ in range(0u, 100) {
                    r.next_u32();
                    task::deschedule();
                    r.next_u64();
                    task::deschedule();
                    r.fill_bytes(&mut v);
                    task::deschedule();
                }
            })
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(())
        }
    }
}
<commit_msg>Windows and OS X fallout<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
    extern crate libc;

    use self::OsRngInner::*;

    use io::{IoResult, File};
    use path::Path;
    use rand::Rng;
    use rand::reader::ReaderRng;
    use result::{Ok, Err};
    use slice::SlicePrelude;
    use mem;
    use os::errno;

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn getrandom(buf: &mut [u8]) -> libc::c_long {
        extern "C" {
            fn syscall(number: libc::c_long, ...) -> libc::c_long;
        }

        #[cfg(target_arch = "x86_64")]
        const NR_GETRANDOM: libc::c_long = 318;
        #[cfg(target_arch = "x86")]
        const NR_GETRANDOM: libc::c_long = 355;
        #[cfg(target_arch = "arm")]
        const NR_GETRANDOM: libc::c_long = 384;

        unsafe {
            syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

    fn getrandom_fill_bytes(v: &mut [u8]) {
        let mut read = 0;
        let len = v.len();
        while read < len {
            let result = getrandom(v[mut read..]);
            if result == -1 {
                let err = errno() as libc::c_int;
                if err == libc::EINTR {
                    continue;
                } else {
                    panic!("unexpected getrandom error: {}", err);
                }
            } else {
                read += result as uint;
            }
        }
    }

    fn getrandom_next_u32() -> u32 {
        let mut buf: [u8, ..4] = [0u8, ..4];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..4], u32>(buf) }
    }

    fn getrandom_next_u64() -> u64 {
        let mut buf: [u8, ..8] = [0u8, ..8];
        getrandom_fill_bytes(&mut buf);
        unsafe { mem::transmute::<[u8, ..8], u64>(buf) }
    }

    #[cfg(all(target_os = "linux",
              any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
    fn is_getrandom_available() -> bool {
        use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed};

        static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL;
        static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL;

        if !GETRANDOM_CHECKED.load(Relaxed) {
            let mut buf: [u8, ..0] = [];
            let result = getrandom(&mut buf);
            let available = if result == -1 {
                let err = errno() as libc::c_int;
                err != libc::ENOSYS
            } else {
                true
            };
            GETRANDOM_AVAILABLE.store(available, Relaxed);
            GETRANDOM_CHECKED.store(true, Relaxed);
            available
        } else {
            GETRANDOM_AVAILABLE.load(Relaxed)
        }
    }

    #[cfg(not(all(target_os = "linux",
                  any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))]
    fn is_getrandom_available() -> bool { false }

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        inner: OsRngInner,
    }

    enum OsRngInner {
        OsGetrandomRng,
        OsReaderRng(ReaderRng<File>),
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            if is_getrandom_available() {
                return Ok(OsRng { inner: OsGetrandomRng });
            }

            let reader = try!(File::open(&Path::new("/dev/urandom")));
            let reader_rng = ReaderRng::new(reader);

            Ok(OsRng { inner: OsReaderRng(reader_rng) })
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u32(),
                OsReaderRng(ref mut rng) => rng.next_u32(),
            }
        }
        fn next_u64(&mut self) -> u64 {
            match self.inner {
                OsGetrandomRng => getrandom_next_u64(),
                OsReaderRng(ref mut rng) => rng.next_u64(),
            }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            match self.inner {
                OsGetrandomRng => getrandom_fill_bytes(v),
                OsReaderRng(ref mut rng) => rng.fill_bytes(v)
            }
        }
    }
}

#[cfg(target_os = "ios")]
mod imp {
    extern crate libc;

    use io::{IoResult};
    use kinds::marker;
    use mem;
    use os;
    use rand::Rng;
    use result::{Ok};
    use self::libc::{c_int, size_t};
    use slice::{SlicePrelude};

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        marker: marker::NoCopy
    }

    #[repr(C)]
    struct SecRandom;

    #[allow(non_upper_case_globals)]
    static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;

    #[link(name = "Security", kind = "framework")]
    extern "C" {
        fn SecRandomCopyBytes(rnd: *const SecRandom,
                              count: size_t, bytes: *mut u8) -> c_int;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            Ok(OsRng {marker: marker::NoCopy} )
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
            };
            if ret == -1 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate libc;

    use io::{IoResult, IoError};
    use mem;
    use ops::Drop;
    use os;
    use rand::Rng;
    use result::{Ok, Err};
    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
    use self::libc::types::os::arch::extra::{LONG_PTR};
    use slice::{SlicePrelude};

    type HCRYPTPROV = LONG_PTR;

    /// A random number generator that retrieves randomness straight from
    /// the operating system. Platform sources:
    ///
    /// - Unix-like systems (Linux, Android, Mac OSX): read directly from
    ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
    /// - Windows: calls `CryptGenRandom`, using the default cryptographic
    ///   service provider with the `PROV_RSA_FULL` type.
    /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
    /// This does not block.
    pub struct OsRng {
        hcryptprov: HCRYPTPROV
    }

    static PROV_RSA_FULL: DWORD = 1;
    static CRYPT_SILENT: DWORD = 64;
    static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;

    #[allow(non_snake_case)]
    extern "system" {
        fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
                                pszContainer: LPCSTR,
                                pszProvider: LPCSTR,
                                dwProvType: DWORD,
                                dwFlags: DWORD) -> BOOL;
        fn CryptGenRandom(hProv: HCRYPTPROV,
                          dwLen: DWORD,
                          pbBuffer: *mut BYTE) -> BOOL;
        fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
    }

    impl OsRng {
        /// Create a new `OsRng`.
        pub fn new() -> IoResult<OsRng> {
            let mut hcp = 0;
            let ret = unsafe {
                CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
                                     PROV_RSA_FULL,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            };

            if ret == 0 {
                Err(IoError::last_error())
            } else {
                Ok(OsRng { hcryptprov: hcp })
            }
        }
    }

    impl Rng for OsRng {
        fn next_u32(&mut self) -> u32 {
            let mut v = [0u8, .. 4];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn next_u64(&mut self) -> u64 {
            let mut v = [0u8, .. 8];
            self.fill_bytes(&mut v);
            unsafe { mem::transmute(v) }
        }
        fn fill_bytes(&mut self, v: &mut [u8]) {
            let ret = unsafe {
                CryptGenRandom(self.hcryptprov, v.len() as DWORD,
                               v.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}", os::last_os_error());
            }
        }
    }

    impl Drop for OsRng {
        fn drop(&mut self) {
            let ret = unsafe {
                CryptReleaseContext(self.hcryptprov, 0)
            };
            if ret == 0 {
                panic!("couldn't release context: {}", os::last_os_error());
            }
        }
    }
}

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

    use super::OsRng;
    use rand::Rng;
    use task;

    #[test]
    fn test_os_rng() {
        let mut r = OsRng::new().unwrap();

        r.next_u32();
        r.next_u64();

        let mut v = [0u8, .. 1000];
        r.fill_bytes(&mut v);
    }

    #[test]
    fn test_os_rng_tasks() {

        let mut txs = vec!();
        for _ in range(0u, 20) {
            let (tx, rx) = channel();
            txs.push(tx);
            task::spawn(proc() {
                // wait until all the tasks are ready to go.
                rx.recv();

                // deschedule to attempt to interleave things as much
                // as possible (XXX: is this a good test?)
                let mut r = OsRng::new().unwrap();
                task::deschedule();
                let mut v = [0u8, .. 1000];

                for _ in range(0u, 100) {
                    r.next_u32();
                    task::deschedule();
                    r.next_u64();
                    task::deschedule();
                    r.fill_bytes(&mut v);
                    task::deschedule();
                }
            })
        }

        // start all the tasks
        for tx in txs.iter() {
            tx.send(())
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::collections::HashMap;
use std::fmt;

use algebra::Operator;
use common::err::Result;
use common::plugin::{PluginManager, TypeRegistry, FuncRegistry};
use common::session::Session;

use node::*;

pub struct LogicalPlanner {
  type_registry: Rc<TypeRegistry>,
  func_registry: Rc<FuncRegistry>
}

impl LogicalPlanner
{
  pub fn new(
    type_registry: Rc<TypeRegistry>,
    func_registry: Rc<FuncRegistry>) -> LogicalPlanner

  {
    LogicalPlanner {
      type_registry: type_registry,
      func_registry: func_registry
    }
  }

  pub fn build(&self, session: &Session, algebra: &Operator) -> Result<LogicalPlan>
  {
    unimplemented!();
  }
}

#[derive(Clone)]
pub struct QueryBlock {
  root: PlanNode
}

#[derive(Clone)]
pub struct LogicalPlan {
  query_blocks: HashMap<i32, QueryBlock>
}<commit_msg>Improved PlanContext.<commit_after>use std::rc::Rc;
use std::collections::HashMap;
use std::fmt;

use algebra::{Operator, Visitor};
use common::err::Result;
use common::plugin::{PluginManager, TypeRegistry, FuncRegistry};
use common::session::Session;

use node::*;

pub struct LogicalPlanner {
  type_registry: Rc<TypeRegistry>,
  func_registry: Rc<FuncRegistry>
}

impl LogicalPlanner
{
  pub fn new(
    type_registry: Rc<TypeRegistry>,
    func_registry: Rc<FuncRegistry>) -> LogicalPlanner

  {
    LogicalPlanner {
      type_registry: type_registry,
      func_registry: func_registry
    }
  }

  pub fn build(&self, session: &Session, algebra: &Operator) -> Result<LogicalPlan>
  {
    unimplemented!();
  }
}

pub struct PlanContext {

}

impl<'v> Visitor<'v, PlanContext> {
  fn visit_dataset(&self, &mut PlanContext, dataset: &'v DataSet) {
  }
}

#[derive(Clone)]
pub struct QueryBlock {
  id  : u32,
  root: PlanNode
}

#[derive(Clone)]
pub struct LogicalPlan {
  root_id     : u32,
  query_blocks: HashMap<u32, QueryBlock>
}<|endoftext|>


<commit_before>#![allow(unused_variables, dead_code)]
#[macro_use]
extern crate r2pipe;
extern crate docopt;
extern crate rustc_serialize;
extern crate radeco_lib;
//extern crate core;

mod radeco;
mod structs;

use rustc_serialize::json;
use docopt::Docopt;
use std::process::exit;
use std::fs::{File};
use std::io::{Write, Read};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_output: String,
    flag_version: bool,
    flag_shell: bool,
    arg_file: Option<String>,
	flag_from_json: bool,
	flag_json_builder: bool,
	cmd_run: bool,
}

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [--json-builder]
  radeco run [options] [<file>]
  radeco --shell <file>
  radeco --output=<output> <file>
  radeco --version

Options:
  -h --help              Show this screen.
  --version              Show version.
  --shell                Run interactive prompt.
  --output=<mode>        Select output mode.
  --from-json            Run radeco based on config and information
				         from input json file. Needs an input file.
  --json-builder         Interactive shell used to build the config
				         json for radeco. When used with run, the
				         config generated is automatically used to
						 run radeco rather than dumping it to a file.
";

//fn radeco_file(args:&Args) -> i32 {
    //let mut r = Radeco::file("/bin/ls".to_owned()).unwrap();
    //if args.flag_shell {
        //r.shell();
    //} else {
        //println!("Batch stuff here");
    //}
    //r.close();
    //0
//}

//fn radeco_pipe(args:&Args) -> i32 {
    //let mut r = Radeco::pipe().unwrap();
    //if args.flag_shell {
        //r.shell();
    //} else {
        //println!("Running radeco via pipe");
		//// TODO get offset, function, bin info, ..
    //}
    //r.close();
    //0
//}

fn write_file(fname: String, res: String) {
	let mut file = File::create(fname).unwrap();
	file.write_all(res.as_bytes()).unwrap();
}

fn json_builder(run: bool) {
	let inp = structs::input_builder();
	let mut runner = inp.validate().unwrap();
	if !run {
		let mut name = inp.name.clone().unwrap();
		let json = json::as_pretty_json(&inp);
		let raw_json = format!("{}", json);
		name.push_str(".json");
		write_file(name, raw_json);
	} else {
		runner.run();
	}
}

fn read_json(fname: String) -> structs::Input {
	let mut raw_json = String::new();
	let _ = File::open(fname).unwrap().read_to_string(&mut raw_json);
	json::decode(&*raw_json).unwrap()
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    if args.flag_version {
        println!("Version: {:?}", VERSION);
        exit(0);
    }
    //if args.arg_file != "" {
        //if args.arg_file == "-" {
            //exit(radeco_pipe(&args));
        //} else {
            //exit(radeco_file(&args));
        //}
    //}

	if args.flag_json_builder {
		json_builder(args.cmd_run);
	}

	if args.flag_from_json {
		if args.arg_file.is_none() {
			println!("{}", USAGE);
		}

		let inp = read_json(args.arg_file.unwrap());
		let mut runner = inp.validate().unwrap();
		runner.run();
	}
}
<commit_msg>Adds dump() to emit output<commit_after>#![allow(unused_variables, dead_code)]
#[macro_use]
extern crate r2pipe;
extern crate docopt;
extern crate rustc_serialize;
extern crate radeco_lib;
//extern crate core;

mod radeco;
mod structs;

use rustc_serialize::json;
use docopt::Docopt;
use std::process::exit;
use std::fs::{File};
use std::io::{Write, Read};

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_output: String,
    flag_version: bool,
    flag_shell: bool,
    arg_file: Option<String>,
	flag_from_json: bool,
	flag_json_builder: bool,
	cmd_run: bool,
}

static USAGE: &'static str = "
radeco. The radare2 decompiler.

Usage:
  radeco <file>
  radeco [--json-builder]
  radeco run [options] [<file>]
  radeco --shell <file>
  radeco --output=<output> <file>
  radeco --version

Options:
  -h --help              Show this screen.
  --version              Show version.
  --shell                Run interactive prompt.
  --output=<mode>        Select output mode.
  --from-json            Run radeco based on config and information
				         from input json file. Needs an input file.
  --json-builder         Interactive shell used to build the config
				         json for radeco. When used with run, the
				         config generated is automatically used to
						 run radeco rather than dumping it to a file.
";

//fn radeco_file(args:&Args) -> i32 {
    //let mut r = Radeco::file("/bin/ls".to_owned()).unwrap();
    //if args.flag_shell {
        //r.shell();
    //} else {
        //println!("Batch stuff here");
    //}
    //r.close();
    //0
//}

//fn radeco_pipe(args:&Args) -> i32 {
    //let mut r = Radeco::pipe().unwrap();
    //if args.flag_shell {
        //r.shell();
    //} else {
        //println!("Running radeco via pipe");
		//// TODO get offset, function, bin info, ..
    //}
    //r.close();
    //0
//}

fn write_file(fname: String, res: String) {
	let mut file = File::create(fname).unwrap();
	file.write_all(res.as_bytes()).unwrap();
}

fn json_builder(run: bool) {
	let inp = structs::input_builder();
	let mut runner = inp.validate().unwrap();
	if !run {
		let mut name = inp.name.clone().unwrap();
		let json = json::as_pretty_json(&inp);
		let raw_json = format!("{}", json);
		name.push_str(".json");
		write_file(name, raw_json);
	} else {
		runner.run();
		runner.dump();
	}
}

fn read_json(fname: String) -> structs::Input {
	let mut raw_json = String::new();
	let _ = File::open(fname).unwrap().read_to_string(&mut raw_json);
	json::decode(&*raw_json).unwrap()
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    if args.flag_version {
        println!("Version: {:?}", VERSION);
        exit(0);
    }
    //if args.arg_file != "" {
        //if args.arg_file == "-" {
            //exit(radeco_pipe(&args));
        //} else {
            //exit(radeco_file(&args));
        //}
    //}

	if args.flag_json_builder {
		json_builder(args.cmd_run);
	}

	if args.flag_from_json {
		if args.arg_file.is_none() {
			println!("{}", USAGE);
		}

		let inp = read_json(args.arg_file.unwrap());
		let mut runner = inp.validate().unwrap();
		runner.run();
		runner.dump();
	}
}
<|endoftext|>


<commit_before>use lib::ParseFrom;
use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potato,
    Berry,
    TreeSap,
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Item::Potato),
            1 => Ok(Item::Berry),
            2 => Ok(Item::TreeSap),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[derive(Debug,Clone)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    pub inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    }
}

impl Player {
    pub fn state (&mut self) -> &mut PlayerState {
        match self {
            &mut Player::AnonymousPlayer { ref mut state } => state,
            &mut Player::RegisteredPlayer { ref mut id, ref mut name, ref mut state } => state,
        }
    }
}

#[allow(non_snake_case)]
pub mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
pub mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}
<commit_msg>Minor: cleanup<commit_after>use lib::ParseFrom;
use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potato,
    Berry,
    TreeSap,
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Item::Potato),
            1 => Ok(Item::Berry),
            2 => Ok(Item::TreeSap),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[derive(Debug,Clone)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    pub inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    },
}

impl Player {
    #[allow(unused_variables)]
    pub fn state (&mut self) -> &mut PlayerState {
        match self {
            &mut Player::AnonymousPlayer { ref mut state } => state,
            &mut Player::RegisteredPlayer { ref mut id, ref mut name, ref mut state } => state,
        }
    }
}

#[allow(non_snake_case)]
pub mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
pub mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::super::{Domain, DspVec, MetaData, NumberSpace, ToSliceMut};
use multicore_support::*;
use numbers::*;
use simd_extensions::*;
/// Trigonometry methods.
pub trait TrigOps {
    /// Calculates the sine of each element in radians.
    ///
    /// # Example
    ///
    /// ```
    /// use std::f32;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(f32::consts::PI/2.0, -f32::consts::PI/2.0).to_real_time_vec();
    /// vector.sin();
    /// assert_eq!([1.0, -1.0], vector[..]);
    /// ```
    fn sin(&mut self);

    /// Calculates the cosine of each element in radians.
    ///
    /// # Example
    ///
    /// ```
    /// use std::f32;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(2.0 * f32::consts::PI, f32::consts::PI).to_real_time_vec();
    /// vector.cos();
    /// assert_eq!([1.0, -1.0], vector[..]);
    /// ```
    fn cos(&mut self);

    /// Calculates the tangent of each element in radians.
    fn tan(&mut self);

    /// Calculates the principal value of the inverse sine of each element in radians.
    fn asin(&mut self);

    /// Calculates the principal value of the inverse cosine of each element in radians.
    fn acos(&mut self);

    /// Calculates the principal value of the inverse tangent of each element in radians.
    fn atan(&mut self);

    /// Calculates the hyperbolic sine each element in radians.
    fn sinh(&mut self);

    /// Calculates the hyperbolic cosine each element in radians.
    fn cosh(&mut self);

    /// Calculates the hyperbolic tangent each element in radians.
    fn tanh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic sine of each element in radians.
    fn asinh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic cosine of each element in radians.
    fn acosh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic
    /// tangent of each element in radians.
    fn atanh(&mut self);
}

/// Roots, powers, exponentials and logarithms.
pub trait PowerOps<T>
where
    T: RealNumber,
{
    /// Gets the square root of all vector elements.
    ///
    /// The sqrt of a negative number gives NaN and not a complex vector.
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 4.0, 9.0, 16.0, 25.0).to_real_time_vec();
    /// vector.sqrt();
    /// assert_eq!([1.0, 2.0, 3.0, 4.0, 5.0], vector[..]);
    /// let mut vector = vec!(-1.0).to_real_time_vec();
    /// vector.sqrt();
    /// assert!(f64::is_nan(vector[0]));
    /// ```
    fn sqrt(&mut self);

    /// Squares all vector elements.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0, 4.0, 5.0).to_real_time_vec();
    /// vector.square();
    /// assert_eq!([1.0, 4.0, 9.0, 16.0, 25.0], vector[..]);
    /// ```
    fn square(&mut self);

    /// Calculates the n-th root of every vector element.
    ///
    /// If the result would be a complex number then the vector will contain a NaN instead.
    /// So the vector
    /// will never convert itself to a complex vector during this operation.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 8.0, 27.0).to_real_time_vec();
    /// vector.root(3.0);
    /// assert_eq!([1.0, 2.0, 3.0], vector[..]);
    /// ```
    fn root(&mut self, degree: T);

    /// Raises every vector element to a floating point power.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.powf(3.0);
    /// assert_eq!([1.0, 8.0, 27.0], vector[..]);
    /// ```
    fn powf(&mut self, exponent: T);

    /// Computes the principal value of natural logarithm of every element in the vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(2.718281828459045, 7.389056, 20.085537).to_real_time_vec();
    /// vector.ln();
    /// let actual = &vector[0..];
    /// let expected = &[1.0, 2.0, 3.0];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn ln(&mut self);

    /// Calculates the natural exponential for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.exp();
    /// let actual = &vector[0..];
    /// let expected = &[2.718281828459045, 7.389056, 20.085537];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn exp(&mut self);

    /// Calculates the logarithm to the given base for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(10.0, 100.0, 1000.0).to_real_time_vec();
    /// vector.log(10.0);
    /// let actual = &vector[0..];
    /// let expected = &[1.0, 2.0, 3.0];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn log(&mut self, base: T);

    /// Calculates the exponential to the given base for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.expf(10.0);
    /// assert_eq!([10.0, 100.0, 1000.0], vector[..]);
    /// ```
    fn expf(&mut self, base: T);
}

const TRIG_COMPLEXITY: Complexity = Complexity::Medium;
const DEF_POW_COMPLEXITY: Complexity = Complexity::Large;

impl<S, T, N, D> TrigOps for DspVec<S, T, N, D>
where
    S: ToSliceMut<T>,
    T: RealNumber,
    N: NumberSpace,
    D: Domain,
{
    fn sin(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.sin(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.sin(), (), TRIG_COMPLEXITY);
        }
    }

    fn cos(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.cos(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.cos(), (), TRIG_COMPLEXITY);
        }
    }

    fn tan(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.tan(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.tan(), (), TRIG_COMPLEXITY);
        }
    }

    fn asin(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.asin(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.asin(), (), TRIG_COMPLEXITY);
        }
    }

    fn acos(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.acos(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.acos(), (), TRIG_COMPLEXITY);
        }
    }

    fn atan(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.atan(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.atan(), (), TRIG_COMPLEXITY);
        }
    }

    fn sinh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.sinh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.sinh(), (), TRIG_COMPLEXITY);
        }
    }

    fn cosh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.cosh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.cosh(), (), TRIG_COMPLEXITY);
        }
    }

    fn tanh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.tanh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.tanh(), (), TRIG_COMPLEXITY);
        }
    }

    fn asinh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.asinh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.asinh(), (), TRIG_COMPLEXITY);
        }
    }

    fn acosh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.acosh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.acosh(), (), TRIG_COMPLEXITY);
        }
    }

    fn atanh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.atanh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.atanh(), (), TRIG_COMPLEXITY);
        }
    }
}

impl<S, T, N, D> PowerOps<T> for DspVec<S, T, N, D>
where
    S: ToSliceMut<T>,
    T: RealNumber,
    N: NumberSpace,
    D: Domain,
{
    fn sqrt(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.sqrt(), (), Complexity::Small);
        } else {
            sel_reg!(self.simd_real_operation::<T>(
                |x, _arg| x.sqrt(),
                |x, _arg| x.sqrt(),
                (),
                Complexity::Small
            ));
        }
    }

    fn square(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x * x, (), Complexity::Small);
        } else {
            sel_reg!(self.simd_real_operation::<T>(
                |x, _arg| x * x,
                |x, _arg| x * x,
                (),
                Complexity::Small
            ));
        }
    }

    fn root(&mut self, degree: T) {
        self.powf(T::one() / degree);
    }

    fn powf(&mut self, exponent: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.powf(y), exponent, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| x.powf(y), exponent, DEF_POW_COMPLEXITY);
        }
    }

    fn ln(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.ln(), (), DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, _arg| x.ln(), (), DEF_POW_COMPLEXITY);
        }
    }

    fn exp(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.exp(), (), DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, _arg| x.exp(), (), DEF_POW_COMPLEXITY);
        }
    }

    fn log(&mut self, base: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.log(y), base, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| x.log(y), base, DEF_POW_COMPLEXITY);
        }
    }

    fn expf(&mut self, base: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.expf(y), base, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| y.powf(x), base, DEF_POW_COMPLEXITY);
        }
    }
}
<commit_msg>Reviewed complexity classes<commit_after>use super::super::{Domain, DspVec, MetaData, NumberSpace, ToSliceMut};
use multicore_support::*;
use numbers::*;
use simd_extensions::*;
/// Trigonometry methods.
pub trait TrigOps {
    /// Calculates the sine of each element in radians.
    ///
    /// # Example
    ///
    /// ```
    /// use std::f32;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(f32::consts::PI/2.0, -f32::consts::PI/2.0).to_real_time_vec();
    /// vector.sin();
    /// assert_eq!([1.0, -1.0], vector[..]);
    /// ```
    fn sin(&mut self);

    /// Calculates the cosine of each element in radians.
    ///
    /// # Example
    ///
    /// ```
    /// use std::f32;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(2.0 * f32::consts::PI, f32::consts::PI).to_real_time_vec();
    /// vector.cos();
    /// assert_eq!([1.0, -1.0], vector[..]);
    /// ```
    fn cos(&mut self);

    /// Calculates the tangent of each element in radians.
    fn tan(&mut self);

    /// Calculates the principal value of the inverse sine of each element in radians.
    fn asin(&mut self);

    /// Calculates the principal value of the inverse cosine of each element in radians.
    fn acos(&mut self);

    /// Calculates the principal value of the inverse tangent of each element in radians.
    fn atan(&mut self);

    /// Calculates the hyperbolic sine each element in radians.
    fn sinh(&mut self);

    /// Calculates the hyperbolic cosine each element in radians.
    fn cosh(&mut self);

    /// Calculates the hyperbolic tangent each element in radians.
    fn tanh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic sine of each element in radians.
    fn asinh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic cosine of each element in radians.
    fn acosh(&mut self);

    /// Calculates the principal value of the inverse hyperbolic
    /// tangent of each element in radians.
    fn atanh(&mut self);
}

/// Roots, powers, exponentials and logarithms.
pub trait PowerOps<T>
where
    T: RealNumber,
{
    /// Gets the square root of all vector elements.
    ///
    /// The sqrt of a negative number gives NaN and not a complex vector.
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 4.0, 9.0, 16.0, 25.0).to_real_time_vec();
    /// vector.sqrt();
    /// assert_eq!([1.0, 2.0, 3.0, 4.0, 5.0], vector[..]);
    /// let mut vector = vec!(-1.0).to_real_time_vec();
    /// vector.sqrt();
    /// assert!(f64::is_nan(vector[0]));
    /// ```
    fn sqrt(&mut self);

    /// Squares all vector elements.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0, 4.0, 5.0).to_real_time_vec();
    /// vector.square();
    /// assert_eq!([1.0, 4.0, 9.0, 16.0, 25.0], vector[..]);
    /// ```
    fn square(&mut self);

    /// Calculates the n-th root of every vector element.
    ///
    /// If the result would be a complex number then the vector will contain a NaN instead.
    /// So the vector
    /// will never convert itself to a complex vector during this operation.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 8.0, 27.0).to_real_time_vec();
    /// vector.root(3.0);
    /// assert_eq!([1.0, 2.0, 3.0], vector[..]);
    /// ```
    fn root(&mut self, degree: T);

    /// Raises every vector element to a floating point power.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.powf(3.0);
    /// assert_eq!([1.0, 8.0, 27.0], vector[..]);
    /// ```
    fn powf(&mut self, exponent: T);

    /// Computes the principal value of natural logarithm of every element in the vector.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(2.718281828459045, 7.389056, 20.085537).to_real_time_vec();
    /// vector.ln();
    /// let actual = &vector[0..];
    /// let expected = &[1.0, 2.0, 3.0];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn ln(&mut self);

    /// Calculates the natural exponential for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.exp();
    /// let actual = &vector[0..];
    /// let expected = &[2.718281828459045, 7.389056, 20.085537];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn exp(&mut self);

    /// Calculates the logarithm to the given base for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::f64;
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(10.0, 100.0, 1000.0).to_real_time_vec();
    /// vector.log(10.0);
    /// let actual = &vector[0..];
    /// let expected = &[1.0, 2.0, 3.0];
    /// assert_eq!(actual.len(), expected.len());
    /// for i in 0..actual.len() {
    ///        assert!(f64::abs(actual[i] - expected[i]) < 1e-4);
    /// }
    /// ```
    fn log(&mut self, base: T);

    /// Calculates the exponential to the given base for every vector element.
    ///
    /// # Example
    ///
    /// ```
    /// use basic_dsp_vector::*;
    /// let mut vector = vec!(1.0, 2.0, 3.0).to_real_time_vec();
    /// vector.expf(10.0);
    /// assert_eq!([10.0, 100.0, 1000.0], vector[..]);
    /// ```
    fn expf(&mut self, base: T);
}

const TRIG_COMPLEXITY: Complexity = Complexity::Medium;
const DEF_POW_COMPLEXITY: Complexity = Complexity::Medium;

impl<S, T, N, D> TrigOps for DspVec<S, T, N, D>
where
    S: ToSliceMut<T>,
    T: RealNumber,
    N: NumberSpace,
    D: Domain,
{
    fn sin(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.sin(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.sin(), (), TRIG_COMPLEXITY);
        }
    }

    fn cos(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.cos(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.cos(), (), TRIG_COMPLEXITY);
        }
    }

    fn tan(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.tan(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.tan(), (), TRIG_COMPLEXITY);
        }
    }

    fn asin(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.asin(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.asin(), (), TRIG_COMPLEXITY);
        }
    }

    fn acos(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.acos(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.acos(), (), TRIG_COMPLEXITY);
        }
    }

    fn atan(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.atan(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.atan(), (), TRIG_COMPLEXITY);
        }
    }

    fn sinh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.sinh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.sinh(), (), TRIG_COMPLEXITY);
        }
    }

    fn cosh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.cosh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.cosh(), (), TRIG_COMPLEXITY);
        }
    }

    fn tanh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.tanh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.tanh(), (), TRIG_COMPLEXITY);
        }
    }

    fn asinh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.asinh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.asinh(), (), TRIG_COMPLEXITY);
        }
    }

    fn acosh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.acosh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.acosh(), (), TRIG_COMPLEXITY);
        }
    }

    fn atanh(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|v, _| v.atanh(), (), TRIG_COMPLEXITY);
        } else {
            self.pure_real_operation(|v, _| v.atanh(), (), TRIG_COMPLEXITY);
        }
    }
}

impl<S, T, N, D> PowerOps<T> for DspVec<S, T, N, D>
where
    S: ToSliceMut<T>,
    T: RealNumber,
    N: NumberSpace,
    D: Domain,
{
    fn sqrt(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.sqrt(), (), Complexity::Small);
        } else {
            sel_reg!(self.simd_real_operation::<T>(
                |x, _arg| x.sqrt(),
                |x, _arg| x.sqrt(),
                (),
                Complexity::Small
            ));
        }
    }

    fn square(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x * x, (), Complexity::Small);
        } else {
            sel_reg!(self.simd_real_operation::<T>(
                |x, _arg| x * x,
                |x, _arg| x * x,
                (),
                Complexity::Small
            ));
        }
    }

    fn root(&mut self, degree: T) {
        self.powf(T::one() / degree);
    }

    fn powf(&mut self, exponent: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.powf(y), exponent, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| x.powf(y), exponent, DEF_POW_COMPLEXITY);
        }
    }

    fn ln(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.ln(), (), DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, _arg| x.ln(), (), DEF_POW_COMPLEXITY);
        }
    }

    fn exp(&mut self) {
        if self.is_complex() {
            self.pure_complex_operation(|x, _arg| x.exp(), (), DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, _arg| x.exp(), (), DEF_POW_COMPLEXITY);
        }
    }

    fn log(&mut self, base: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.log(y), base, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| x.log(y), base, DEF_POW_COMPLEXITY);
        }
    }

    fn expf(&mut self, base: T) {
        if self.is_complex() {
            self.pure_complex_operation(|x, y| x.expf(y), base, DEF_POW_COMPLEXITY);
        } else {
            self.pure_real_operation(|x, y| y.powf(x), base, DEF_POW_COMPLEXITY);
        }
    }
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct JobRequireVariablePair {
    pub id: i32,
    pub fk_job: i32,
    pub fk_variable_pair: i32,
}

pub fn table_create_job_require_variable_pair(conn: &Connection) {
    let load_table = conn.execute("CREATE TABLE JOB_REQUIRE_VALUE (
                  id            INTEGER PRIMARY KEY ASC,
                  job           INTEGER NOT NULL,
                  variable_pair INTEGER NOT NULL,
                  FOREIGN KEY(job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(variable_pair) REFERENCES VARIABLE_PAIR(id) ON UPDATE CASCADE
                  )", &[]);
    if load_table.is_err() {
        println!("table_create_job Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_job_require_variable_pair(conn: &Connection, job :&i32, variable_pair: &i32) -> Result<i32, &'static str> {
    let me = JobRequireVariablePair {
        id: 0,
        fk_job: *job,
        fk_variable_pair: *variable_pair,

    };
    let variable_pair_instance = conn.execute("INSERT INTO JOB_REQUIRE_VALUE (job, variable_pair)
                  VALUES (?1, ?2)",
                 &[&me.fk_job, &me.fk_variable_pair]);
    if variable_pair_instance.is_err() {
        return Err("Insert failed");
    }
    variable_pair_instance.unwrap();
    return Ok(0);
}

pub fn list_job_require_variable_pair(conn: &Connection)-> Vec<JobRequireVariablePair> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable_pair  FROM VARIABLE_PAIR").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    });
    let mut items = Vec::<JobRequireVariablePair>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn job_require_variable_pair_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable_pair FROM VARIABLE_PAIR").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_pair {:?}", person.unwrap());
    }
}

pub fn pk_job_require_variable_pair_by_all(conn: &Connection, job: &i32, variable_pair: &i32) -> Result<i32, &'static str>{
    let mut output = 0;
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable_pair  FROM VARIABLE_PAIR WHERE name = ?1").unwrap();
    let variable_pair_iter = stmt.query_map(&[job, variable_pair], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    });
    if variable_pair_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_pair_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill= person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<commit_msg>Rename columns<commit_after>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct JobRequireVariablePair {
    pub id: i32,
    pub fk_job: i32,
    pub fk_variable_pair: i32,
}

pub fn table_create_job_require_variable_pair(conn: &Connection) {
    let load_table = conn.execute("CREATE TABLE JOB_REQUIRE_VALUE (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_job           INTEGER NOT NULL,
                  fk_variable_pair INTEGER NOT NULL,
                  FOREIGN KEY(fk_job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(fk_variable_pair) REFERENCES VARIABLE_PAIR(id) ON UPDATE CASCADE
                  )", &[]);
    if load_table.is_err() {
        println!("table_create_job Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_job_require_variable_pair(conn: &Connection, job :&i32, variable_pair: &i32) -> Result<i32, &'static str> {
    let me = JobRequireVariablePair {
        id: 0,
        fk_job: *job,
        fk_variable_pair: *variable_pair,

    };
    let variable_pair_instance = conn.execute("INSERT INTO JOB_REQUIRE_VALUE (fk_job, fk_variable_pair)
                  VALUES (?1, ?2)",
                 &[&me.fk_job, &me.fk_variable_pair]);
    if variable_pair_instance.is_err() {
        return Err("Insert failed");
    }
    variable_pair_instance.unwrap();
    return Ok(0);
}

pub fn list_job_require_variable_pair(conn: &Connection)-> Vec<JobRequireVariablePair> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable_pair  FROM JOB_REQUIRE_VALUE").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    });
    let mut items = Vec::<JobRequireVariablePair>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn job_require_variable_pair_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable_pair FROM JOB_REQUIRE_VALUE").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_pair {:?}", person.unwrap());
    }
}

pub fn pk_job_require_variable_pair_by_all(conn: &Connection, job: &i32, variable_pair: &i32) -> Result<i32, &'static str>{
    let mut output = 0;
    let mut stmt = conn.prepare("SELECT JOB_REQUIRE_VALUE.id, JOB_REQUIRE_VALUE.fk_job, JOB_REQUIRE_VALUE.fk_variable_pair  FROM JOB_REQUIRE_VALUE WHERE JOB_REQUIRE_VALUE.fk_job = ?1 AND JOB_REQUIRE_VALUE.fk_variable_pair = ?2").unwrap();
    let variable_pair_iter = stmt.query_map(&[job, variable_pair], |row| {
        JobRequireVariablePair {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable_pair: row.get(2),
        }
    });
    if variable_pair_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_pair_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill= person.unwrap();
        output = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(output);
    }
    return Err("None found");
}
<|endoftext|>