<commit_before>use sodiumoxide::crypto::hash::sha256::Digest;

use crate::script::{Builder, Script, OpFrame};
use crate::crypto::{PublicKey, double_sha256};
use super::*;

pub const SCRIPT_HASH_BUF_PREFIX: u8 = 0x03;

#[derive(Debug, Clone, PartialEq)]
pub struct ScriptHash(Digest);

impl ScriptHash {
    #[inline]
    pub fn from_slice(slice: &[u8]) -> Option<ScriptHash> {
        let digest = Digest::from_slice(slice)?;
        Some(ScriptHash(digest))
    }
}

impl Wif<ScriptHash> for ScriptHash {
    fn from_wif(s: &str) -> Result<ScriptHash, WifError> {
        if s.len() < 3 || &s[0..3] != PUB_ADDRESS_PREFIX {
            return Err(WifError::new(WifErrorKind::InvalidPrefix))
        }
        let raw = match bs58::decode(&s[3..]).into_vec() {
            Ok(bytes) => bytes,
            Err(_) => return Err(WifError::new(WifErrorKind::InvalidBs58Encoding))
        };
        if raw.len() != 37 {
            return Err(WifError::new(WifErrorKind::InvalidLen))
        } else if raw[0] != SCRIPT_HASH_BUF_PREFIX {
            return Err(WifError::new(WifErrorKind::InvalidPrefix))
        }

        let prefixed_key = &raw[0..raw.len() - 4];
        {
            let checksum_a = &raw[raw.len() - 4 .. raw.len()];
            let checksum_b = &double_sha256(prefixed_key)[0..4];
            if checksum_a != checksum_b {
                return Err(WifError::new(WifErrorKind::InvalidChecksum))
            }
        }

        let key = &prefixed_key[1 .. prefixed_key.len()];
        Ok(ScriptHash::from_slice(key).unwrap())
    }

    fn to_wif(&self) -> Box<str> {
        let mut buf: Vec<u8> = Vec::<u8>::with_capacity(37);
        buf.push(SCRIPT_HASH_BUF_PREFIX);
        buf.extend_from_slice(self.0.as_ref());

        let checksum = &double_sha256(&buf)[0..4];
        buf.extend_from_slice(checksum);

        let mut s = bs58::encode(buf).into_string();
        s.insert_str(0, PUB_ADDRESS_PREFIX);
        s.into_boxed_str()
    }
}

impl From<&Script> for ScriptHash {
    fn from(script: &Script) -> ScriptHash {
        let hash = double_sha256(script);
        ScriptHash(hash)
    }
}

impl From<PublicKey> for ScriptHash {
    fn from(key: PublicKey) -> ScriptHash {
        let builder = Builder::new()
                .push(OpFrame::PubKey(key.clone()))
                .push(OpFrame::OpCheckSig);
        (&builder.build()).into()
    }
}

impl From<&PublicKey> for ScriptHash {
    fn from(key: &PublicKey) -> ScriptHash {
        let builder = Builder::new()
                .push(OpFrame::PubKey(key.clone()))
                .push(OpFrame::OpCheckSig);
        (&builder.build()).into()
    }
}

impl AsRef<[u8]> for ScriptHash {
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}
<commit_msg>Remove unnecessary cloning on the public key when converting to ScriptHash<commit_after>use sodiumoxide::crypto::hash::sha256::Digest;

use crate::script::{Builder, Script, OpFrame};
use crate::crypto::{PublicKey, double_sha256};
use super::*;

pub const SCRIPT_HASH_BUF_PREFIX: u8 = 0x03;

#[derive(Debug, Clone, PartialEq)]
pub struct ScriptHash(Digest);

impl ScriptHash {
    #[inline]
    pub fn from_slice(slice: &[u8]) -> Option<ScriptHash> {
        let digest = Digest::from_slice(slice)?;
        Some(ScriptHash(digest))
    }
}

impl Wif<ScriptHash> for ScriptHash {
    fn from_wif(s: &str) -> Result<ScriptHash, WifError> {
        if s.len() < 3 || &s[0..3] != PUB_ADDRESS_PREFIX {
            return Err(WifError::new(WifErrorKind::InvalidPrefix))
        }
        let raw = match bs58::decode(&s[3..]).into_vec() {
            Ok(bytes) => bytes,
            Err(_) => return Err(WifError::new(WifErrorKind::InvalidBs58Encoding))
        };
        if raw.len() != 37 {
            return Err(WifError::new(WifErrorKind::InvalidLen))
        } else if raw[0] != SCRIPT_HASH_BUF_PREFIX {
            return Err(WifError::new(WifErrorKind::InvalidPrefix))
        }

        let prefixed_key = &raw[0..raw.len() - 4];
        {
            let checksum_a = &raw[raw.len() - 4 .. raw.len()];
            let checksum_b = &double_sha256(prefixed_key)[0..4];
            if checksum_a != checksum_b {
                return Err(WifError::new(WifErrorKind::InvalidChecksum))
            }
        }

        let key = &prefixed_key[1 .. prefixed_key.len()];
        Ok(ScriptHash::from_slice(key).unwrap())
    }

    fn to_wif(&self) -> Box<str> {
        let mut buf: Vec<u8> = Vec::<u8>::with_capacity(37);
        buf.push(SCRIPT_HASH_BUF_PREFIX);
        buf.extend_from_slice(self.0.as_ref());

        let checksum = &double_sha256(&buf)[0..4];
        buf.extend_from_slice(checksum);

        let mut s = bs58::encode(buf).into_string();
        s.insert_str(0, PUB_ADDRESS_PREFIX);
        s.into_boxed_str()
    }
}

impl From<&Script> for ScriptHash {
    fn from(script: &Script) -> ScriptHash {
        let hash = double_sha256(script);
        ScriptHash(hash)
    }
}

impl From<PublicKey> for ScriptHash {
    fn from(key: PublicKey) -> ScriptHash {
        let builder = Builder::new()
                .push(OpFrame::PubKey(key))
                .push(OpFrame::OpCheckSig);
        (&builder.build()).into()
    }
}

impl From<&PublicKey> for ScriptHash {
    fn from(key: &PublicKey) -> ScriptHash {
        let builder = Builder::new()
                .push(OpFrame::PubKey(key.clone()))
                .push(OpFrame::OpCheckSig);
        (&builder.build()).into()
    }
}

impl AsRef<[u8]> for ScriptHash {
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}
<|endoftext|>


<commit_before>use std::collections::LinkedList;

// https://leetcode.com/problems/number-of-people-aware-of-a-secret/
pub fn people_aware_of_secret(n: i32, delay: i32, forget: i32) -> i32 {
    let mut answer: i64 = if 1 + forget > n { 1 } else { 0 };
    let mut list: LinkedList<i32> = LinkedList::new();
    list.push_back(1);
    loop {
        let front = list.pop_front();
        match front {
            Some(day) => {
                if day > n {
                    break;
                }
                let secret_day = day + delay;
                for d in secret_day..(secret_day + (forget - delay)) {
                    if d > n {
                        break;
                    }
                    list.push_back(d);
                    if d + forget > n {
                        answer += 1;
                    }
                }
            }
            None => break,
        }
    }
    (answer % 1_000_000_007) as i32
}

fn main() {
    // println!("{}", people_aware_of_secret(6, 2, 4)); // 5
    // println!("{}", people_aware_of_secret(4, 1, 3)); // 6
    // println!("{}", people_aware_of_secret(10, 3, 5)); // 5
    // println!("{}", people_aware_of_secret(1000, 500, 600)); // 100
    println!("{}", people_aware_of_secret(1000, 2, 1000)); // 517691607
}
<commit_msg>Update problem 2327<commit_after>use std::collections::LinkedList;

// https://leetcode.com/problems/number-of-people-aware-of-a-secret/
pub fn people_aware_of_secret(n: i32, delay: i32, forget: i32) -> i32 {
    let mut answer: i64 = if 1 + forget > n { 1 } else { 0 };
    let mut list: LinkedList<i32> = LinkedList::new();
    list.push_back(1);
    loop {
        let front = list.pop_front();
        match front {
            Some(day) => {
                if day > n {
                    break;
                }
                let secret_day = day + delay;
                for d in secret_day..(secret_day + (forget - delay)) {
                    if d > n {
                        break;
                    }
                    list.push_back(d);
                    if d + forget > n {
                        answer += 1;
                    }
                }
            }
            None => break,
        }
    }
    (answer % 1_000_000_007) as i32
}

fn main() {
    println!("{}", people_aware_of_secret(6, 2, 4)); // 5
    println!("{}", people_aware_of_secret(4, 1, 3)); // 6
    println!("{}", people_aware_of_secret(10, 3, 5)); // 5
    println!("{}", people_aware_of_secret(1000, 500, 600)); // 100
    println!("{}", people_aware_of_secret(100, 20, 30)); // 6775
    println!("{}", people_aware_of_secret(1000, 2, 1000)); // 517691607
}
<|endoftext|>


<commit_before>//! Middleware that blocks requests with no user-agent header

use super::prelude::*;

use crate::util::request_header;

// Can't derive debug because of Handler.
#[allow(missing_debug_implementations)]
#[derive(Default)]
pub struct RequireUserAgent {
    handler: Option<Box<dyn Handler>>,
}

impl AroundMiddleware for RequireUserAgent {
    fn with_handler(&mut self, handler: Box<dyn Handler>) {
        self.handler = Some(handler);
    }
}

impl Handler for RequireUserAgent {
    fn call(&self, req: &mut dyn RequestExt) -> AfterResult {
        let agent = request_header(req, header::USER_AGENT);
        let has_user_agent = agent != "" && agent != "Amazon CloudFront";
        let is_download = req.path().ends_with("download");
        if !has_user_agent && !is_download {
            super::log_request::add_custom_metadata(req, "cause", "no user agent");
            let body = format!(
                include_str!("no_user_agent_message.txt"),
                request_header(req, "x-request-id"),
            );

            Response::builder()
                .status(StatusCode::FORBIDDEN)
                .header(header::CONTENT_LENGTH, body.len())
                .body(Body::from_vec(body.into_bytes()))
                .map_err(box_error)
        } else {
            self.handler.as_ref().unwrap().call(req)
        }
    }
}
<commit_msg>Move CDN user-agent to environment variable<commit_after>//! Middleware that blocks requests with no user-agent header
//!
//! By default the middleware will treat "" and "Amazon CloudFront" as a missing user-agent. To
//! change the 2nd value, set `WEB_CDN_USER_AGENT` to the appropriate string. To disable the CDN
//! check, set `WEB_CDN_USER_AGENT` to the empty string.
//!
//! Requests to the download endpoint are always allowed, to support versions of cargo older than
//! 0.17 (released alongside rustc 1.17).

use super::prelude::*;
use std::env;

use crate::util::request_header;

// Can't derive debug because of Handler.
#[allow(missing_debug_implementations)]
#[derive(Default)]
pub struct RequireUserAgent {
    cdn_user_agent: String,
    handler: Option<Box<dyn Handler>>,
}

impl AroundMiddleware for RequireUserAgent {
    fn with_handler(&mut self, handler: Box<dyn Handler>) {
        self.cdn_user_agent =
            env::var("WEB_CDN_USER_AGENT").unwrap_or_else(|_| "Amazon CloudFront".into());
        self.handler = Some(handler);
    }
}

impl Handler for RequireUserAgent {
    fn call(&self, req: &mut dyn RequestExt) -> AfterResult {
        let agent = request_header(req, header::USER_AGENT);
        let has_user_agent = agent != "" && agent != self.cdn_user_agent;
        let is_download = req.path().ends_with("download");
        if !has_user_agent && !is_download {
            super::log_request::add_custom_metadata(req, "cause", "no user agent");
            let body = format!(
                include_str!("no_user_agent_message.txt"),
                request_header(req, "x-request-id"),
            );

            Response::builder()
                .status(StatusCode::FORBIDDEN)
                .header(header::CONTENT_LENGTH, body.len())
                .body(Body::from_vec(body.into_bytes()))
                .map_err(box_error)
        } else {
            self.handler.as_ref().unwrap().call(req)
        }
    }
}
<|endoftext|>


<commit_before>extern mod OpenCL;
use OpenCL::CL::*;
use OpenCL::hl::*;

fn main() {
    let platforms = get_platforms();

    error!("%?", platforms);

    do platforms.map |platform| { get_devices(*platform); }
}
<commit_msg>trying to get the devices in the first platform to test the get_devices wrapper.<commit_after>extern mod OpenCL;
use OpenCL::CL::*;
use OpenCL::hl::*;

fn main() {
    let platforms = get_platforms();

    error!("%?", platforms);

    get_devices(*platforms[0]);
}
<|endoftext|>


<commit_before>use nickel::{
    Params
};
use std;

#[derive(Debug)]
pub struct Validators;

#[derive(Debug)]
pub struct FormValidationErrors;

pub trait FormValidator {
    fn validate(form_data: &Params)
            -> Result<Self, FormValidationErrors>
            where Self: std::marker::Sized {
        let _validators = Self::validators();
        Ok(Self::fill_form(form_data)?)
    }
    fn validators() -> Validators;
    fn fill_form(form_data: &Params)
            -> Result<Self, FormValidationErrors>
            where Self: std::marker::Sized;
}<commit_msg>Template for create_validator<commit_after>use nickel::{
    Params,
    BodyError,
};
use std;
use std::collections::HashMap;

#[derive(Debug)]
pub struct Validators;

#[derive(Debug)]
pub enum FormValidationErrors {
    FieldNotExist
}

pub trait FormValidator {
    fn validate(form_data: &Params)
            -> Result<Self, FormValidationErrors>
            where Self: std::marker::Sized {
        let _validators = Self::validators();
        create_validator(&form_data);
        Ok(Self::fill_form(&form_data)?)
    }
    fn validators() -> Validators;
    fn fill_form(form_data: &Params)
            -> Result<Self, FormValidationErrors>
            where Self: std::marker::Sized;
}

fn create_validator(form_data: &Params) -> Result<(), FormValidationErrors> {
    let mut validation_errors: HashMap<&str, Vec<FormValidationErrors>> = HashMap::new();
    let field_name = "done.a1";
    let get_form = form_data.get(field_name);

    match get_form {
        Some(x) => println!("{:#?}", x),
        _ => {
            let err = vec![FormValidationErrors::FieldNotExist];
            validation_errors.insert(field_name, err);
        },
    }
    let get_data: Option<String> = form_data.get(field_name)
        .or_else(|| { println!("Field not exist"); None })
        .and_then(|o| o.parse().ok());
    println!("{:#?}", get_data);

    Ok(())
}
<|endoftext|>


<commit_before>#[cfg(feature = "bigdecimal")]
mod bigdecimal {
    extern crate bigdecimal;
    extern crate num_bigint;
    extern crate num_integer;
    extern crate num_traits;

    use self::bigdecimal::BigDecimal;
    use self::num_bigint::{BigInt, BigUint, Sign};
    use self::num_integer::Integer;
    use self::num_traits::{Signed, ToPrimitive, Zero};
    use std::io::prelude::*;

    use deserialize::{self, FromSql};
    use pg::data_types::PgNumeric;
    use pg::Pg;
    use serialize::{self, Output, ToSql};
    use sql_types::Numeric;

    #[cfg(feature = "unstable")]
    use std::convert::{TryFrom, TryInto};
    #[cfg(feature = "unstable")]
    use std::error::Error;

    /// Iterator over the digits of a big uint in base 10k.
    /// The digits will be returned in little endian order.
    struct ToBase10000(Option<BigUint>);

    impl Iterator for ToBase10000 {
        type Item = i16;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.take().map(|v| {
                let (div, rem) = v.div_rem(&BigUint::from(10_000u16));
                if !div.is_zero() {
                    self.0 = Some(div);
                }
                rem.to_i16().expect("10000 always fits in an i16")
            })
        }
    }

    fn pg_decimal_to_bigdecimal(numeric: &PgNumeric) -> deserialize::Result<BigDecimal> {
        let (sign, weight, scale, digits) = match *numeric {
            PgNumeric::Positive {
                weight,
                scale,
                ref digits,
            } => (Sign::Plus, weight, scale, digits),
            PgNumeric::Negative {
                weight,
                scale,
                ref digits,
            } => (Sign::Minus, weight, scale, digits),
            PgNumeric::NaN => return Err(Box::from("NaN is not (yet) supported in BigDecimal")),
        };

        let mut result = BigUint::default();
        let count = digits.len() as i64;
        for digit in digits {
            result *= BigUint::from(10_000u64);
            result += BigUint::from(*digit as u64);
        }
        // First digit got factor 10_000^(digits.len() - 1), but should get 10_000^weight
        let correction_exp = 4 * (i64::from(weight) - count + 1);
        let result = BigDecimal::new(BigInt::from_biguint(sign, result), -correction_exp)
            .with_scale(i64::from(scale));
        Ok(result)
    }

    #[cfg(feature = "unstable")]
    impl<'a> TryFrom<&'a PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: &'a PgNumeric) -> deserialize::Result<Self> {
            pg_decimal_to_bigdecimal(numeric)
        }
    }

    #[cfg(feature = "unstable")]
    impl TryFrom<PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: PgNumeric) -> deserialize::Result<Self> {
            (&numeric).try_into()
        }
    }

    impl<'a> From<&'a BigDecimal> for PgNumeric {
        fn from(decimal: &'a BigDecimal) -> Self {
            let (mut integer, scale) = decimal.as_bigint_and_exponent();
            let scale = scale as u16;
            integer = integer.abs();

            // Ensure that the decimal will always lie on a digit boundary
            for _ in 0..(4 - scale % 4) {
                #[allow(assign_op_pattern)] // No `std::ops::MulAssign` impl for `BigInt`
                integer = integer * 10;
            }
            let integer = integer.to_biguint().expect("integer is always positive");

            let mut digits = ToBase10000(Some(integer)).collect::<Vec<_>>();
            digits.reverse();
            let digits_after_decimal = scale as u16 / 4 + 1;
            let weight = digits.len() as i16 - digits_after_decimal as i16 - 1;

            let unnecessary_zeroes = if weight >= 0 {
                let index_of_decimal = (weight + 1) as usize;
                digits
                    .get(index_of_decimal..)
                    .expect("enough digits exist")
                    .iter()
                    .rev()
                    .take_while(|i| i.is_zero())
                    .count()
            } else {
                0
            };

            let relevant_digits = digits.len() - unnecessary_zeroes;
            digits.truncate(relevant_digits);

            match decimal.sign() {
                Sign::Plus => PgNumeric::Positive {
                    digits,
                    scale,
                    weight,
                },
                Sign::Minus => PgNumeric::Negative {
                    digits,
                    scale,
                    weight,
                },
                Sign::NoSign => PgNumeric::Positive {
                    digits: vec![0],
                    scale: 0,
                    weight: 0,
                },
            }
        }
    }

    impl From<BigDecimal> for PgNumeric {
        fn from(bigdecimal: BigDecimal) -> Self {
            (&bigdecimal).into()
        }
    }

    impl ToSql<Numeric, Pg> for BigDecimal {
        fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
            let numeric = PgNumeric::from(self);
            ToSql::<Numeric, Pg>::to_sql(&numeric, out)
        }
    }

    impl FromSql<Numeric, Pg> for BigDecimal {
        fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result<Self> {
            // FIXME: Use the TryFrom impl when try_from is stable
            let numeric = PgNumeric::from_sql(numeric)?;
            pg_decimal_to_bigdecimal(&numeric)
        }
    }

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

        #[test]
        fn bigdecimal_to_pgnumeric_converts_digits_to_base_10000() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![10],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 0],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 0,
                digits: vec![1, 0, 0],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_properly_adjusts_scale() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.0").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 2,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000.0001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 4,
                digits: vec![1, 0, 0, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("0.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: -1,
                scale: 1,
                digits: vec![1000],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_retains_sign() {
            let decimal = BigDecimal::from_str("123.456").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("-123.456").unwrap();
            let expected = PgNumeric::Negative {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        #[cfg(feature = "unstable")]
        fn pg_numeric_to_bigdecimal_works() {
            let expected = BigDecimal::from_str("123.456").unwrap();
            let pg_numeric = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);

            let expected = BigDecimal::from_str("-56.78").unwrap();
            let pg_numeric = PgNumeric::Negative {
                weight: 0,
                scale: 2,
                digits: vec![56, 7800],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);
        }
    }
}
<commit_msg>Add `cfg_attr` to clippy warning<commit_after>#[cfg(feature = "bigdecimal")]
mod bigdecimal {
    extern crate bigdecimal;
    extern crate num_bigint;
    extern crate num_integer;
    extern crate num_traits;

    use self::bigdecimal::BigDecimal;
    use self::num_bigint::{BigInt, BigUint, Sign};
    use self::num_integer::Integer;
    use self::num_traits::{Signed, ToPrimitive, Zero};
    use std::io::prelude::*;

    use deserialize::{self, FromSql};
    use pg::data_types::PgNumeric;
    use pg::Pg;
    use serialize::{self, Output, ToSql};
    use sql_types::Numeric;

    #[cfg(feature = "unstable")]
    use std::convert::{TryFrom, TryInto};
    #[cfg(feature = "unstable")]
    use std::error::Error;

    /// Iterator over the digits of a big uint in base 10k.
    /// The digits will be returned in little endian order.
    struct ToBase10000(Option<BigUint>);

    impl Iterator for ToBase10000 {
        type Item = i16;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.take().map(|v| {
                let (div, rem) = v.div_rem(&BigUint::from(10_000u16));
                if !div.is_zero() {
                    self.0 = Some(div);
                }
                rem.to_i16().expect("10000 always fits in an i16")
            })
        }
    }

    fn pg_decimal_to_bigdecimal(numeric: &PgNumeric) -> deserialize::Result<BigDecimal> {
        let (sign, weight, scale, digits) = match *numeric {
            PgNumeric::Positive {
                weight,
                scale,
                ref digits,
            } => (Sign::Plus, weight, scale, digits),
            PgNumeric::Negative {
                weight,
                scale,
                ref digits,
            } => (Sign::Minus, weight, scale, digits),
            PgNumeric::NaN => return Err(Box::from("NaN is not (yet) supported in BigDecimal")),
        };

        let mut result = BigUint::default();
        let count = digits.len() as i64;
        for digit in digits {
            result *= BigUint::from(10_000u64);
            result += BigUint::from(*digit as u64);
        }
        // First digit got factor 10_000^(digits.len() - 1), but should get 10_000^weight
        let correction_exp = 4 * (i64::from(weight) - count + 1);
        let result = BigDecimal::new(BigInt::from_biguint(sign, result), -correction_exp)
            .with_scale(i64::from(scale));
        Ok(result)
    }

    #[cfg(feature = "unstable")]
    impl<'a> TryFrom<&'a PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: &'a PgNumeric) -> deserialize::Result<Self> {
            pg_decimal_to_bigdecimal(numeric)
        }
    }

    #[cfg(feature = "unstable")]
    impl TryFrom<PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: PgNumeric) -> deserialize::Result<Self> {
            (&numeric).try_into()
        }
    }

    impl<'a> From<&'a BigDecimal> for PgNumeric {
        fn from(decimal: &'a BigDecimal) -> Self {
            let (mut integer, scale) = decimal.as_bigint_and_exponent();
            let scale = scale as u16;
            integer = integer.abs();

            // Ensure that the decimal will always lie on a digit boundary
            for _ in 0..(4 - scale % 4) {
                // NOTE: No `std::ops::MulAssign` impl for `BigInt`
                #[cfg_attr(feature = "cargo-clippy", allow(assign_op_pattern))]
                integer = integer * 10;
            }
            let integer = integer.to_biguint().expect("integer is always positive");

            let mut digits = ToBase10000(Some(integer)).collect::<Vec<_>>();
            digits.reverse();
            let digits_after_decimal = scale as u16 / 4 + 1;
            let weight = digits.len() as i16 - digits_after_decimal as i16 - 1;

            let unnecessary_zeroes = if weight >= 0 {
                let index_of_decimal = (weight + 1) as usize;
                digits
                    .get(index_of_decimal..)
                    .expect("enough digits exist")
                    .iter()
                    .rev()
                    .take_while(|i| i.is_zero())
                    .count()
            } else {
                0
            };

            let relevant_digits = digits.len() - unnecessary_zeroes;
            digits.truncate(relevant_digits);

            match decimal.sign() {
                Sign::Plus => PgNumeric::Positive {
                    digits,
                    scale,
                    weight,
                },
                Sign::Minus => PgNumeric::Negative {
                    digits,
                    scale,
                    weight,
                },
                Sign::NoSign => PgNumeric::Positive {
                    digits: vec![0],
                    scale: 0,
                    weight: 0,
                },
            }
        }
    }

    impl From<BigDecimal> for PgNumeric {
        fn from(bigdecimal: BigDecimal) -> Self {
            (&bigdecimal).into()
        }
    }

    impl ToSql<Numeric, Pg> for BigDecimal {
        fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
            let numeric = PgNumeric::from(self);
            ToSql::<Numeric, Pg>::to_sql(&numeric, out)
        }
    }

    impl FromSql<Numeric, Pg> for BigDecimal {
        fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result<Self> {
            // FIXME: Use the TryFrom impl when try_from is stable
            let numeric = PgNumeric::from_sql(numeric)?;
            pg_decimal_to_bigdecimal(&numeric)
        }
    }

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

        #[test]
        fn bigdecimal_to_pgnumeric_converts_digits_to_base_10000() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![10],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 0],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 0,
                digits: vec![1, 0, 0],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_properly_adjusts_scale() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.0").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 2,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000.0001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 4,
                digits: vec![1, 0, 0, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("0.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: -1,
                scale: 1,
                digits: vec![1000],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_retains_sign() {
            let decimal = BigDecimal::from_str("123.456").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("-123.456").unwrap();
            let expected = PgNumeric::Negative {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        #[cfg(feature = "unstable")]
        fn pg_numeric_to_bigdecimal_works() {
            let expected = BigDecimal::from_str("123.456").unwrap();
            let pg_numeric = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);

            let expected = BigDecimal::from_str("-56.78").unwrap();
            let pg_numeric = PgNumeric::Negative {
                weight: 0,
                scale: 2,
                digits: vec![56, 7800],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);
        }
    }
}
<|endoftext|>


<commit_before>/// from: https://raw.githubusercontent.com/chriskrycho/newrustacean.com/master/src/e002.rs

/// This struct is simple but useful to see how borrowing and moving work.
#[derive(Debug)]
pub struct Circle {
    /// X position of the circle's origin.
    pub x: f64,
    /// Y position of the circle's origin
    pub y: f64,
    /// Radius of the circle
    pub r: f64,

    pub w: Boxx,
}

#[derive(Debug)]
pub struct Boxx {
    pub x: f64,
    pub y: f64,
}

//const nil:Circle= Circle{x:1,y:2,r:3,w:nul};
//const nul:Circle= Circle{x:1,y:2,r:3,w:nil};

impl Drop for Circle {
    fn drop(&mut self) {
        println!("Dropping! {:?}",self);
    }
}

impl Circle {
    /// Creates a `Circle` instance centered on the "origin" (x = 0, y = 0).
    fn origin() -> Circle {
        Circle {
            x: 1.2,
            y: 3.4,
            r: 5.6,
            w: Boxx{x:1.0, y:2.0},
        }
    }

    pub fn by_borrow_x(&self) -> &f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        &self.x
    }

    pub fn by_take(self) -> Boxx {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.w  //it is moved out... unless defined the trait Drop on the type Circle!
    }

 /*   pub fn by_take2(self) -> f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.x
    }*/

    pub fn by_borrow(&self) -> &Boxx {
        println!("borrowing box");
        &self.w
    }
}

fn main() {
    // Constructors can have default behavior, like this one.
    let immutable = Circle::origin();

    {
        let b = immutable.by_borrow();
        println!("showing borrowed box: {:?}", b);
    }
    {
        let x = immutable.by_borrow_x();
        println!("showing borrowed x: {:?}", x);
    }
//    let y= immutable.by_take2();
    let by_take_box = immutable.by_take();//TODO: what happened with y,z? or even x? they got destroyed? so the return is a copy/clone then? since self.w is returned! ok, so i'm assuming since the box is moved out, the others are just destroyed; but how is the box moved out? memmove?
    println!("By take: {:?}", by_take_box);
    //println!("Does the circle still exist? {:?}", immutable);//no
}

<commit_msg>but it works for simple field types!<commit_after>/// from: https://raw.githubusercontent.com/chriskrycho/newrustacean.com/master/src/e002.rs

/// This struct is simple but useful to see how borrowing and moving work.
#[derive(Debug)]
pub struct Circle {
    /// X position of the circle's origin.
    pub x: f64,
    /// Y position of the circle's origin
    pub y: f64,
    /// Radius of the circle
    pub r: f64,

    pub w: Boxx,
}

#[derive(Debug)]
pub struct Boxx {
    pub x: f64,
    pub y: f64,
}

//const nil:Circle= Circle{x:1,y:2,r:3,w:nul};
//const nul:Circle= Circle{x:1,y:2,r:3,w:nil};

impl Drop for Circle {
    fn drop(&mut self) {
        println!("Dropping! {:?}",self);
    }
}

impl Circle {
    /// Creates a `Circle` instance centered on the "origin" (x = 0, y = 0).
    fn origin() -> Circle {
        Circle {
            x: 1.2,
            y: 3.4,
            r: 5.6,
            w: Boxx{x:1.0, y:2.0},
        }
    }

    pub fn by_borrow_x(&self) -> &f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        &self.x
    }

/*    pub fn by_take(self) -> Boxx {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.w  //it is moved out... unless defined the trait Drop on the type Circle!
    }*/

    pub fn by_take2(self) -> f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.x //it is "moved?" out... and works even if Drop is defined on type Circle! (unlike for self.w)
            //ok, it is copied I guess, since self.x such a simple type
    }

    pub fn by_borrow(&self) -> &Boxx {
        println!("borrowing box");
        &self.w
    }
}

fn main() {
    // Constructors can have default behavior, like this one.
    let immutable = Circle::origin();

    {
        let b = immutable.by_borrow();
        println!("showing borrowed box: {:?}", b);
    }
    {
        let x = immutable.by_borrow_x();
        println!("showing borrowed x: {:?}", x);
    }
//    let y= immutable.by_take2();
    let by_take_box = immutable.by_take2();//TODO: what happened with y,z? or even x? they got destroyed? so the return is a copy/clone then? since self.w is returned! ok, so i'm assuming since the box is moved out, the others are just destroyed; but how is the box moved out? memmove?
    println!("By take: {:?}", by_take_box);
    //println!("Does the circle still exist? {:?}", immutable);//no
}

<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! This module contains shared types and messages for use by devtools/script.
//! The traits are here instead of in script so that the devtools crate can be
//! modified independently of the rest of Servo.

#![crate_name = "devtools_traits"]
#![crate_type = "rlib"]

#![allow(non_snake_case)]
#![deny(unsafe_code)]

#![feature(custom_derive, plugin)]
#![plugin(serde_macros, plugins)]

#[macro_use]
extern crate bitflags;

extern crate ipc_channel;
extern crate msg;
extern crate rustc_serialize;
extern crate serde;
extern crate url;
extern crate hyper;
extern crate util;
extern crate time;

use rustc_serialize::{Decodable, Decoder};
use msg::constellation_msg::{PipelineId, WorkerId};
use util::str::DOMString;
use url::Url;

use hyper::header::Headers;
use hyper::http::RawStatus;
use hyper::method::Method;
use ipc_channel::ipc::IpcSender;
use time::Duration;

use std::net::TcpStream;

// Information would be attached to NewGlobal to be received and show in devtools.
// Extend these fields if we need more information.
#[derive(Deserialize, Serialize)]
pub struct DevtoolsPageInfo {
    pub title: DOMString,
    pub url: Url
}

/// Messages to instruct the devtools server to update its known actors/state
/// according to changes in the browser.
pub enum DevtoolsControlMsg {
    /// Messages from tasks in the chrome process (resource/constellation/devtools)
    FromChrome(ChromeToDevtoolsControlMsg),
    /// Messages from script tasks
    FromScript(ScriptToDevtoolsControlMsg),
}

/// Events that the devtools server must act upon.
pub enum ChromeToDevtoolsControlMsg {
    /// A new client has connected to the server.
    AddClient(TcpStream),
    /// The browser is shutting down.
    ServerExitMsg,
    /// A network event occurred (request, reply, etc.). The actor with the
    /// provided name should be notified.
    NetworkEvent(String, NetworkEvent),
}

#[derive(Deserialize, Serialize)]
/// Events that the devtools server must act upon.
pub enum ScriptToDevtoolsControlMsg {
    /// A new global object was created, associated with a particular pipeline.
    /// The means of communicating directly with it are provided.
    NewGlobal((PipelineId, Option<WorkerId>),
              IpcSender<DevtoolScriptControlMsg>,
              DevtoolsPageInfo),
    /// A particular page has invoked the console API.
    ConsoleAPI(PipelineId, ConsoleMessage, Option<WorkerId>),
    /// An animation frame with the given timestamp was processed in a script task.
    /// The actor with the provided name should be notified.
    FramerateTick(String, f64),
}

/// Serialized JS return values
/// TODO: generalize this beyond the EvaluateJS message?
#[derive(Deserialize, Serialize)]
pub enum EvaluateJSReply {
    VoidValue,
    NullValue,
    BooleanValue(bool),
    NumberValue(f64),
    StringValue(String),
    ActorValue { class: String, uuid: String },
}

#[derive(Deserialize, Serialize)]
pub struct AttrInfo {
    pub namespace: String,
    pub name: String,
    pub value: String,
}

#[derive(Deserialize, Serialize)]
pub struct NodeInfo {
    pub uniqueId: String,
    pub baseURI: String,
    pub parent: String,
    pub nodeType: u16,
    pub namespaceURI: String,
    pub nodeName: String,
    pub numChildren: usize,

    pub name: String,
    pub publicId: String,
    pub systemId: String,

    pub attrs: Vec<AttrInfo>,

    pub isDocumentElement: bool,

    pub shortValue: String,
    pub incompleteValue: bool,
}

#[derive(PartialEq, Eq, Deserialize, Serialize)]
pub enum TracingMetadata {
    Default,
    IntervalStart,
    IntervalEnd,
    Event,
    EventBacktrace,
}

#[derive(Deserialize, Serialize)]
pub struct TimelineMarker {
    pub name: String,
    pub metadata: TracingMetadata,
    pub time: PreciseTime,
    pub stack: Option<Vec<()>>,
}

#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
pub enum TimelineMarkerType {
    Reflow,
    DOMEvent,
}

/// The properties of a DOM node as computed by layout.
#[derive(Deserialize, Serialize)]
pub struct ComputedNodeLayout {
    pub width: f32,
    pub height: f32,
}

/// Messages to process in a particular script task, as instructed by a devtools client.
#[derive(Deserialize, Serialize)]
pub enum DevtoolScriptControlMsg {
    /// Evaluate a JS snippet in the context of the global for the given pipeline.
    EvaluateJS(PipelineId, String, IpcSender<EvaluateJSReply>),
    /// Retrieve the details of the root node (ie. the document) for the given pipeline.
    GetRootNode(PipelineId, IpcSender<NodeInfo>),
    /// Retrieve the details of the document element for the given pipeline.
    GetDocumentElement(PipelineId, IpcSender<NodeInfo>),
    /// Retrieve the details of the child nodes of the given node in the given pipeline.
    GetChildren(PipelineId, String, IpcSender<Vec<NodeInfo>>),
    /// Retrieve the computed layout properties of the given node in the given pipeline.
    GetLayout(PipelineId, String, IpcSender<ComputedNodeLayout>),
    /// Retrieve all stored console messages for the given pipeline.
    GetCachedMessages(PipelineId, CachedConsoleMessageTypes, IpcSender<Vec<CachedConsoleMessage>>),
    /// Update a given node's attributes with a list of modifications.
    ModifyAttribute(PipelineId, String, Vec<Modification>),
    /// Request live console messages for a given pipeline (true if desired, false otherwise).
    WantsLiveNotifications(PipelineId, bool),
    /// Request live notifications for a given set of timeline events for a given pipeline.
    SetTimelineMarkers(PipelineId, Vec<TimelineMarkerType>, IpcSender<TimelineMarker>),
    /// Withdraw request for live timeline notifications for a given pipeline.
    DropTimelineMarkers(PipelineId, Vec<TimelineMarkerType>),
    /// Request a callback directed at the given actor name from the next animation frame
    /// executed in the given pipeline.
    RequestAnimationFrame(PipelineId, String),
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct Modification {
    pub attributeName: String,
    pub newValue: Option<String>,
}

impl Decodable for Modification {
    fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
        d.read_struct("Modification", 2, |d|
            Ok(Modification {
                attributeName: try!(d.read_struct_field("attributeName", 0, |d| Decodable::decode(d))),
                newValue: match d.read_struct_field("newValue", 1, |d| Decodable::decode(d)) {
                    Ok(opt) => opt,
                    Err(_) => None
                }
            })
        )
    }
}

#[derive(Clone, Deserialize, Serialize)]
pub enum LogLevel {
    Log,
    Debug,
    Info,
    Warn,
    Error,
}

#[derive(Clone, Deserialize, Serialize)]
pub struct ConsoleMessage {
    pub message: String,
    pub logLevel: LogLevel,
    pub filename: String,
    pub lineNumber: u32,
    pub columnNumber: u32,
}

bitflags! {
    #[derive(Deserialize, Serialize)]
    flags CachedConsoleMessageTypes: u8 {
        const PAGE_ERROR  = 1 << 0,
        const CONSOLE_API = 1 << 1,
    }
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct PageError {
    pub _type: String,
    pub errorMessage: String,
    pub sourceName: String,
    pub lineText: String,
    pub lineNumber: u32,
    pub columnNumber: u32,
    pub category: String,
    pub timeStamp: u64,
    pub error: bool,
    pub warning: bool,
    pub exception: bool,
    pub strict: bool,
    pub private: bool,
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct ConsoleAPI {
    pub _type: String,
    pub level: String,
    pub filename: String,
    pub lineNumber: u32,
    pub functionName: String,
    pub timeStamp: u64,
    pub private: bool,
    pub arguments: Vec<String>,
}

#[derive(Deserialize, Serialize)]
pub enum CachedConsoleMessage {
    PageError(PageError),
    ConsoleAPI(ConsoleAPI),
}

#[derive(Clone)]
pub enum NetworkEvent {
    HttpRequest(Url, Method, Headers, Option<Vec<u8>>),
    HttpResponse(Option<Headers>, Option<RawStatus>, Option<Vec<u8>>)
}

impl TimelineMarker {
    pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
        TimelineMarker {
            name: name,
            metadata: metadata,
            time: PreciseTime::now(),
            stack: None,
        }
    }
}

/// A replacement for `time::PreciseTime` that isn't opaque, so we can serialize it.
///
/// The reason why this doesn't go upstream is that `time` is slated to be part of Rust's standard
/// library, which definitely can't have any dependencies on `serde`. But `serde` can't implement
/// `Deserialize` and `Serialize` itself, because `time::PreciseTime` is opaque! A Catch-22. So I'm
/// duplicating the definition here.
#[derive(Copy, Clone, Deserialize, Serialize)]
pub struct PreciseTime(u64);

impl PreciseTime {
    pub fn now() -> PreciseTime {
        PreciseTime(time::precise_time_ns())
    }

    pub fn to(&self, later: PreciseTime) -> Duration {
        Duration::nanoseconds((later.0 - self.0) as i64)
    }
}
<commit_msg>Eta-reduce some functions in devtools<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! This module contains shared types and messages for use by devtools/script.
//! The traits are here instead of in script so that the devtools crate can be
//! modified independently of the rest of Servo.

#![crate_name = "devtools_traits"]
#![crate_type = "rlib"]

#![allow(non_snake_case)]
#![deny(unsafe_code)]

#![feature(custom_derive, plugin)]
#![plugin(serde_macros, plugins)]

#[macro_use]
extern crate bitflags;

extern crate ipc_channel;
extern crate msg;
extern crate rustc_serialize;
extern crate serde;
extern crate url;
extern crate hyper;
extern crate util;
extern crate time;

use rustc_serialize::{Decodable, Decoder};
use msg::constellation_msg::{PipelineId, WorkerId};
use util::str::DOMString;
use url::Url;

use hyper::header::Headers;
use hyper::http::RawStatus;
use hyper::method::Method;
use ipc_channel::ipc::IpcSender;
use time::Duration;

use std::net::TcpStream;

// Information would be attached to NewGlobal to be received and show in devtools.
// Extend these fields if we need more information.
#[derive(Deserialize, Serialize)]
pub struct DevtoolsPageInfo {
    pub title: DOMString,
    pub url: Url
}

/// Messages to instruct the devtools server to update its known actors/state
/// according to changes in the browser.
pub enum DevtoolsControlMsg {
    /// Messages from tasks in the chrome process (resource/constellation/devtools)
    FromChrome(ChromeToDevtoolsControlMsg),
    /// Messages from script tasks
    FromScript(ScriptToDevtoolsControlMsg),
}

/// Events that the devtools server must act upon.
pub enum ChromeToDevtoolsControlMsg {
    /// A new client has connected to the server.
    AddClient(TcpStream),
    /// The browser is shutting down.
    ServerExitMsg,
    /// A network event occurred (request, reply, etc.). The actor with the
    /// provided name should be notified.
    NetworkEvent(String, NetworkEvent),
}

#[derive(Deserialize, Serialize)]
/// Events that the devtools server must act upon.
pub enum ScriptToDevtoolsControlMsg {
    /// A new global object was created, associated with a particular pipeline.
    /// The means of communicating directly with it are provided.
    NewGlobal((PipelineId, Option<WorkerId>),
              IpcSender<DevtoolScriptControlMsg>,
              DevtoolsPageInfo),
    /// A particular page has invoked the console API.
    ConsoleAPI(PipelineId, ConsoleMessage, Option<WorkerId>),
    /// An animation frame with the given timestamp was processed in a script task.
    /// The actor with the provided name should be notified.
    FramerateTick(String, f64),
}

/// Serialized JS return values
/// TODO: generalize this beyond the EvaluateJS message?
#[derive(Deserialize, Serialize)]
pub enum EvaluateJSReply {
    VoidValue,
    NullValue,
    BooleanValue(bool),
    NumberValue(f64),
    StringValue(String),
    ActorValue { class: String, uuid: String },
}

#[derive(Deserialize, Serialize)]
pub struct AttrInfo {
    pub namespace: String,
    pub name: String,
    pub value: String,
}

#[derive(Deserialize, Serialize)]
pub struct NodeInfo {
    pub uniqueId: String,
    pub baseURI: String,
    pub parent: String,
    pub nodeType: u16,
    pub namespaceURI: String,
    pub nodeName: String,
    pub numChildren: usize,

    pub name: String,
    pub publicId: String,
    pub systemId: String,

    pub attrs: Vec<AttrInfo>,

    pub isDocumentElement: bool,

    pub shortValue: String,
    pub incompleteValue: bool,
}

#[derive(PartialEq, Eq, Deserialize, Serialize)]
pub enum TracingMetadata {
    Default,
    IntervalStart,
    IntervalEnd,
    Event,
    EventBacktrace,
}

#[derive(Deserialize, Serialize)]
pub struct TimelineMarker {
    pub name: String,
    pub metadata: TracingMetadata,
    pub time: PreciseTime,
    pub stack: Option<Vec<()>>,
}

#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
pub enum TimelineMarkerType {
    Reflow,
    DOMEvent,
}

/// The properties of a DOM node as computed by layout.
#[derive(Deserialize, Serialize)]
pub struct ComputedNodeLayout {
    pub width: f32,
    pub height: f32,
}

/// Messages to process in a particular script task, as instructed by a devtools client.
#[derive(Deserialize, Serialize)]
pub enum DevtoolScriptControlMsg {
    /// Evaluate a JS snippet in the context of the global for the given pipeline.
    EvaluateJS(PipelineId, String, IpcSender<EvaluateJSReply>),
    /// Retrieve the details of the root node (ie. the document) for the given pipeline.
    GetRootNode(PipelineId, IpcSender<NodeInfo>),
    /// Retrieve the details of the document element for the given pipeline.
    GetDocumentElement(PipelineId, IpcSender<NodeInfo>),
    /// Retrieve the details of the child nodes of the given node in the given pipeline.
    GetChildren(PipelineId, String, IpcSender<Vec<NodeInfo>>),
    /// Retrieve the computed layout properties of the given node in the given pipeline.
    GetLayout(PipelineId, String, IpcSender<ComputedNodeLayout>),
    /// Retrieve all stored console messages for the given pipeline.
    GetCachedMessages(PipelineId, CachedConsoleMessageTypes, IpcSender<Vec<CachedConsoleMessage>>),
    /// Update a given node's attributes with a list of modifications.
    ModifyAttribute(PipelineId, String, Vec<Modification>),
    /// Request live console messages for a given pipeline (true if desired, false otherwise).
    WantsLiveNotifications(PipelineId, bool),
    /// Request live notifications for a given set of timeline events for a given pipeline.
    SetTimelineMarkers(PipelineId, Vec<TimelineMarkerType>, IpcSender<TimelineMarker>),
    /// Withdraw request for live timeline notifications for a given pipeline.
    DropTimelineMarkers(PipelineId, Vec<TimelineMarkerType>),
    /// Request a callback directed at the given actor name from the next animation frame
    /// executed in the given pipeline.
    RequestAnimationFrame(PipelineId, String),
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct Modification {
    pub attributeName: String,
    pub newValue: Option<String>,
}

impl Decodable for Modification {
    fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
        d.read_struct("Modification", 2, |d|
            Ok(Modification {
                attributeName: try!(d.read_struct_field("attributeName", 0, Decodable::decode)),
                newValue: match d.read_struct_field("newValue", 1, Decodable::decode) {
                    Ok(opt) => opt,
                    Err(_) => None
                }
            })
        )
    }
}

#[derive(Clone, Deserialize, Serialize)]
pub enum LogLevel {
    Log,
    Debug,
    Info,
    Warn,
    Error,
}

#[derive(Clone, Deserialize, Serialize)]
pub struct ConsoleMessage {
    pub message: String,
    pub logLevel: LogLevel,
    pub filename: String,
    pub lineNumber: u32,
    pub columnNumber: u32,
}

bitflags! {
    #[derive(Deserialize, Serialize)]
    flags CachedConsoleMessageTypes: u8 {
        const PAGE_ERROR  = 1 << 0,
        const CONSOLE_API = 1 << 1,
    }
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct PageError {
    pub _type: String,
    pub errorMessage: String,
    pub sourceName: String,
    pub lineText: String,
    pub lineNumber: u32,
    pub columnNumber: u32,
    pub category: String,
    pub timeStamp: u64,
    pub error: bool,
    pub warning: bool,
    pub exception: bool,
    pub strict: bool,
    pub private: bool,
}

#[derive(RustcEncodable, Deserialize, Serialize)]
pub struct ConsoleAPI {
    pub _type: String,
    pub level: String,
    pub filename: String,
    pub lineNumber: u32,
    pub functionName: String,
    pub timeStamp: u64,
    pub private: bool,
    pub arguments: Vec<String>,
}

#[derive(Deserialize, Serialize)]
pub enum CachedConsoleMessage {
    PageError(PageError),
    ConsoleAPI(ConsoleAPI),
}

#[derive(Clone)]
pub enum NetworkEvent {
    HttpRequest(Url, Method, Headers, Option<Vec<u8>>),
    HttpResponse(Option<Headers>, Option<RawStatus>, Option<Vec<u8>>)
}

impl TimelineMarker {
    pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
        TimelineMarker {
            name: name,
            metadata: metadata,
            time: PreciseTime::now(),
            stack: None,
        }
    }
}

/// A replacement for `time::PreciseTime` that isn't opaque, so we can serialize it.
///
/// The reason why this doesn't go upstream is that `time` is slated to be part of Rust's standard
/// library, which definitely can't have any dependencies on `serde`. But `serde` can't implement
/// `Deserialize` and `Serialize` itself, because `time::PreciseTime` is opaque! A Catch-22. So I'm
/// duplicating the definition here.
#[derive(Copy, Clone, Deserialize, Serialize)]
pub struct PreciseTime(u64);

impl PreciseTime {
    pub fn now() -> PreciseTime {
        PreciseTime(time::precise_time_ns())
    }

    pub fn to(&self, later: PreciseTime) -> Duration {
        Duration::nanoseconds((later.0 - self.0) as i64)
    }
}
<|endoftext|>


<commit_before>//!
//! Values manipulated by endpoints
//!

use std::time::Duration;
use std::cmp::{PartialOrd, Ordering};

extern crate chrono;
use self::chrono::{DateTime, Local};

extern crate serde_json;

///
/// The type of values manipulated by endpoints.
///
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub enum Type {
    ///
    /// # Trivial values
    ///

    /// An empty value. Used for instance to inform that a countdown
    /// has reached 0 or that a device is ready.
    Unit,

    /// A boolean. Used for instance for on-off switches, presence
    /// detectors, etc.
    Bool,

    ///
    /// # Time
    ///

    /// A duration. Used for instance in countdowns.
    Duration,

    /// A precise timestamp. Used for instance to determine when an
    /// event has taken place.
    TimeStamp,

    Temperature,
    String,
    ///
    /// ...
    ///
    Color,
    Json,
    Binary,
    ExtNumeric,
}

/// A temperature. Internal representation may be either Fahrenheit or
/// Celcius. The FoxBox adapters are expected to perform conversions
/// to the format requested by their devices.
#[derive(Debug, Clone, PartialEq)]
pub enum Temperature {
    /// Fahrenheit
    F(f64),
    /// Celcius
    C(f64),
}

impl Temperature {
    /// Get a temperature in Fahrenheit.
    pub fn as_f(&self) -> f64 {
        unimplemented!();
    }

    /// Get a temperature in Celcius.
    pub fn as_c(&self) -> f64 {
        unimplemented!();
    }
}

impl PartialOrd for Temperature {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.as_c().partial_cmp(&other.as_c())
    }
}

/// A color. Internal representation may vary. The FoxBox adapters are
/// expected to perform conversions to the format requested by their
/// device.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Color {
    RGBA(f64, f64, f64, f64, f64)
}

/// Representation of an object in JSON. It is often (albeit not
/// always) possible to choose a more precise data structure for
/// representing values send/accepted by a service. If possible,
/// adapters should rather pick such more precise data structure.
#[derive(Debug, Clone, PartialEq)]
pub struct Json(serde_json::value::Value);

impl PartialOrd for Json {
    /// Two Json objects are never comparable to each other.
    fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
        None
    }
}

/// A data structure holding a numeric value of a type that has not
/// been standardized yet.
#[derive(Debug, Clone, PartialEq)]
pub struct ExtNumeric {
    pub value: f64,

    /// The vendor. Used for namespacing purposes, to avoid
    /// confusing two incompatible extensions with similar
    /// names. For instance, "foxlink@mozilla.com".
    pub vendor: String,

    /// Identification of the adapter introducing this value.
    /// Designed to aid with tracing and debugging.
    pub adapter: String,

    /// A string describing the nature of the value, designed to
    /// aid with type-checking.
    ///
    /// Examples: `"GroundHumidity"`.
    pub kind: String,
}

impl PartialOrd for ExtNumeric {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.vendor != other.vendor {
            return None;
        } else if self.kind != other.kind {
            return None;
        } else {
            self.value.partial_cmp(&other.value)
        }
    }
}

/// Representation of an actual value that can be sent to/received
/// from a service.
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
    Unit,
    Bool(bool),
    Duration(Duration),
    TimeStamp(chrono::DateTime<Local>),
    Temperature(Temperature),
    Color(Color),
    String(String),

    // FIXME: Add more as we identify needs

    /// A numeric value representing a unit that has not been
    /// standardized yet into the API.
    ExtNumeric(ExtNumeric),
    Json(Json),
    Binary {data: Vec<u8>, mimetype: String}
}

impl Value {
    pub fn get_type(&self) -> Type {
        match *self {
            Value::Unit => Type::Unit,
            Value::Bool(_) => Type::Bool,
            Value::String(_) => Type::String,
            Value::Duration(_) => Type::Duration,
            Value::TimeStamp(_) => Type::TimeStamp,
            Value::Temperature(_) => Type::Temperature,
            Value::Color(_) => Type::Color,
            Value::Json(_) => Type::Json,
            Value::Binary{..} => Type::Binary,
            Value::ExtNumeric(_) => Type::ExtNumeric,
        }
    }
}

impl PartialOrd for Value {
    /// Two values of the same type can be compared using the usual
    /// comparison for values of this type. Two values of distinct
    /// types cannot be compared.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        use self::Value::*;
        use std::cmp::Ordering::*;
        match (self, other) {
            (&Unit, &Unit) => Some(Equal),
            (&Unit, _) => None,

            (&Bool(a), &Bool(b)) => a.partial_cmp(&b),
            (&Bool(_), _) => None,

            (&Duration(ref a), &Duration(ref b)) => a.partial_cmp(b),
            (&Duration(_), _) => None,

            (&TimeStamp(ref a), &TimeStamp(ref b)) => a.partial_cmp(b),
            (&TimeStamp(_), _) => None,

            (&Temperature(ref a), &Temperature(ref b)) => a.partial_cmp(b),
            (&Temperature(_), _) => None,

            (&Color(ref a), &Color(ref b)) => a.partial_cmp(b),
            (&Color(_), _) => None,

            (&ExtNumeric(ref a), &ExtNumeric(ref b)) => a.partial_cmp(b),
            (&ExtNumeric(_), _) => None,

            (&String(ref a), &String(ref b)) => a.partial_cmp(b),
            (&String(_), _) => None,

            (&Json(ref a), &Json(ref b)) => a.partial_cmp(b),
            (&Json(_), _) => None,

            (&Binary{mimetype: ref a_mimetype, data: ref a_data},
             &Binary{mimetype: ref b_mimetype, data: ref b_data}) if a_mimetype == b_mimetype => a_data.partial_cmp(b_data),
            (&Binary{..}, _) => None,
        }
    }
}
<commit_msg>[fxbox/taxonomy] Json is now public<commit_after>//!
//! Values manipulated by endpoints
//!

use std::time::Duration;
use std::cmp::{PartialOrd, Ordering};

extern crate chrono;
use self::chrono::{DateTime, Local};

extern crate serde_json;

///
/// The type of values manipulated by endpoints.
///
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub enum Type {
    ///
    /// # Trivial values
    ///

    /// An empty value. Used for instance to inform that a countdown
    /// has reached 0 or that a device is ready.
    Unit,

    /// A boolean. Used for instance for on-off switches, presence
    /// detectors, etc.
    Bool,

    ///
    /// # Time
    ///

    /// A duration. Used for instance in countdowns.
    Duration,

    /// A precise timestamp. Used for instance to determine when an
    /// event has taken place.
    TimeStamp,

    Temperature,
    String,
    ///
    /// ...
    ///
    Color,
    Json,
    Binary,
    ExtNumeric,
}

/// A temperature. Internal representation may be either Fahrenheit or
/// Celcius. The FoxBox adapters are expected to perform conversions
/// to the format requested by their devices.
#[derive(Debug, Clone, PartialEq)]
pub enum Temperature {
    /// Fahrenheit
    F(f64),
    /// Celcius
    C(f64),
}

impl Temperature {
    /// Get a temperature in Fahrenheit.
    pub fn as_f(&self) -> f64 {
        unimplemented!();
    }

    /// Get a temperature in Celcius.
    pub fn as_c(&self) -> f64 {
        unimplemented!();
    }
}

impl PartialOrd for Temperature {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.as_c().partial_cmp(&other.as_c())
    }
}

/// A color. Internal representation may vary. The FoxBox adapters are
/// expected to perform conversions to the format requested by their
/// device.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Color {
    RGBA(f64, f64, f64, f64, f64)
}

/// Representation of an object in JSON. It is often (albeit not
/// always) possible to choose a more precise data structure for
/// representing values send/accepted by a service. If possible,
/// adapters should rather pick such more precise data structure.
#[derive(Debug, Clone, PartialEq)]
pub struct Json(pub serde_json::value::Value);

impl PartialOrd for Json {
    /// Two Json objects are never comparable to each other.
    fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
        None
    }
}

/// A data structure holding a numeric value of a type that has not
/// been standardized yet.
#[derive(Debug, Clone, PartialEq)]
pub struct ExtNumeric {
    pub value: f64,

    /// The vendor. Used for namespacing purposes, to avoid
    /// confusing two incompatible extensions with similar
    /// names. For instance, "foxlink@mozilla.com".
    pub vendor: String,

    /// Identification of the adapter introducing this value.
    /// Designed to aid with tracing and debugging.
    pub adapter: String,

    /// A string describing the nature of the value, designed to
    /// aid with type-checking.
    ///
    /// Examples: `"GroundHumidity"`.
    pub kind: String,
}

impl PartialOrd for ExtNumeric {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.vendor != other.vendor {
            return None;
        } else if self.kind != other.kind {
            return None;
        } else {
            self.value.partial_cmp(&other.value)
        }
    }
}

/// Representation of an actual value that can be sent to/received
/// from a service.
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
    Unit,
    Bool(bool),
    Duration(Duration),
    TimeStamp(chrono::DateTime<Local>),
    Temperature(Temperature),
    Color(Color),
    String(String),

    // FIXME: Add more as we identify needs

    /// A numeric value representing a unit that has not been
    /// standardized yet into the API.
    ExtNumeric(ExtNumeric),
    Json(Json),
    Binary {data: Vec<u8>, mimetype: String}
}

impl Value {
    pub fn get_type(&self) -> Type {
        match *self {
            Value::Unit => Type::Unit,
            Value::Bool(_) => Type::Bool,
            Value::String(_) => Type::String,
            Value::Duration(_) => Type::Duration,
            Value::TimeStamp(_) => Type::TimeStamp,
            Value::Temperature(_) => Type::Temperature,
            Value::Color(_) => Type::Color,
            Value::Json(_) => Type::Json,
            Value::Binary{..} => Type::Binary,
            Value::ExtNumeric(_) => Type::ExtNumeric,
        }
    }
}

impl PartialOrd for Value {
    /// Two values of the same type can be compared using the usual
    /// comparison for values of this type. Two values of distinct
    /// types cannot be compared.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        use self::Value::*;
        use std::cmp::Ordering::*;
        match (self, other) {
            (&Unit, &Unit) => Some(Equal),
            (&Unit, _) => None,

            (&Bool(a), &Bool(b)) => a.partial_cmp(&b),
            (&Bool(_), _) => None,

            (&Duration(ref a), &Duration(ref b)) => a.partial_cmp(b),
            (&Duration(_), _) => None,

            (&TimeStamp(ref a), &TimeStamp(ref b)) => a.partial_cmp(b),
            (&TimeStamp(_), _) => None,

            (&Temperature(ref a), &Temperature(ref b)) => a.partial_cmp(b),
            (&Temperature(_), _) => None,

            (&Color(ref a), &Color(ref b)) => a.partial_cmp(b),
            (&Color(_), _) => None,

            (&ExtNumeric(ref a), &ExtNumeric(ref b)) => a.partial_cmp(b),
            (&ExtNumeric(_), _) => None,

            (&String(ref a), &String(ref b)) => a.partial_cmp(b),
            (&String(_), _) => None,

            (&Json(ref a), &Json(ref b)) => a.partial_cmp(b),
            (&Json(_), _) => None,

            (&Binary{mimetype: ref a_mimetype, data: ref a_data},
             &Binary{mimetype: ref b_mimetype, data: ref b_data}) if a_mimetype == b_mimetype => a_data.partial_cmp(b_data),
            (&Binary{..}, _) => None,
        }
    }
}
<|endoftext|>


<commit_before>use std::num::{One, Zero};
use std::rand::{Rand, Rng, RngUtil};
use std::cmp::ApproxEq;
use traits::ring::Ring;
use traits::division_ring::DivisionRing;
use traits::rlmul::{RMul, LMul};
use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::rotation::{Rotation, Rotate, Rotatable};
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
use traits::homogeneous::ToHomogeneous;
use traits::indexable::Indexable;
use vec::Vec1;
use mat::{Mat2, Mat3};
use vec::Vec3;

#[deriving(Eq, ToStr)]
pub struct Rotmat<M>
{ priv submat: M }

pub fn rotmat2<N: Copy + Trigonometric + Neg<N>>(angle: N) -> Rotmat<Mat2<N>>
{
  let coa = angle.cos();
  let sia = angle.sin();

  Rotmat
  { submat: Mat2::new( [ copy coa, -sia, copy sia, copy coa ] ) }
}

pub fn rotmat3<N: Copy + Trigonometric + Ring>
(axis: &Vec3<N>, angle: N) -> Rotmat<Mat3<N>>
{
  let _1        = One::one::<N>();
  let ux        = copy axis.at[0];
  let uy        = copy axis.at[1];
  let uz        = copy axis.at[2];
  let sqx       = ux * ux;
  let sqy       = uy * uy;
  let sqz       = uz * uz;
  let cos       = angle.cos();
  let one_m_cos = _1 - cos;
  let sin       = angle.sin();

  Rotmat {
    submat: Mat3::new( [
      (sqx + (_1 - sqx) * cos),
      (ux * uy * one_m_cos - uz * sin),
      (ux * uz * one_m_cos + uy * sin),

      (ux * uy * one_m_cos + uz * sin),
      (sqy + (_1 - sqy) * cos),
      (uy * uz * one_m_cos - ux * sin),

      (ux * uz * one_m_cos - uy * sin),
      (uy * uz * one_m_cos + ux * sin),
      (sqz + (_1 - sqz) * cos) ] )
  }
}

impl<N: Trigonometric + DivisionRing + Copy>
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
{
  #[inline]
  fn rotation(&self) -> Vec1<N>
  { Vec1::new([ -(self.submat.at((0, 1)) / self.submat.at((0, 0))).atan() ]) }

  #[inline]
  fn inv_rotation(&self) -> Vec1<N>
  { -self.rotation() }

  #[inline]
  fn rotate_by(&mut self, rot: &Vec1<N>)
  { *self = self.rotated(rot) }
}

impl<N: Trigonometric + DivisionRing + Copy>
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
{
  #[inline]
  fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
  { rotmat2(copy rot.at[0]) * *self }
}

impl<N: Copy + Trigonometric + DivisionRing>
Rotation<(Vec3<N>, N)> for Rotmat<Mat3<N>>
{
  #[inline]
  fn rotation(&self) -> (Vec3<N>, N)
  { fail!("Not yet implemented.") }
  #[inline]

  fn inv_rotation(&self) -> (Vec3<N>, N)
  { fail!("Not yet implemented.") }

  #[inline]
  fn rotate_by(&mut self, rot: &(Vec3<N>, N))
  { *self = self.rotated(rot) }
}

impl<N: Copy + Trigonometric + DivisionRing>
Rotatable<(Vec3<N>, N), Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
{
  #[inline]
  fn rotated(&self, &(axis, angle): &(Vec3<N>, N)) -> Rotmat<Mat3<N>>
  { rotmat3(&axis, angle) * *self }
}

impl<N: Copy + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
{
  #[inline]
  fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
  { rotmat2(rng.gen()) }
}

impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
{
  #[inline]
  fn rotate(&self, v: &V) -> V
  { self.rmul(v) }

  #[inline]
  fn inv_rotate(&self, v: &V) -> V
  { self.lmul(v) }
}

impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M>
{
  #[inline]
  fn transform_vec(&self, v: &V) -> V
  { self.rotate(v) }

  #[inline]
  fn inv_transform(&self, v: &V) -> V
  { self.inv_rotate(v) }
}

impl<N: Copy + Rand + Trigonometric + Ring>
Rand for Rotmat<Mat3<N>>
{
  #[inline]
  fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
  { rotmat3(&rng.gen(), rng.gen()) }
}

impl<M: Dim> Dim for Rotmat<M>
{
  #[inline]
  fn dim() -> uint
  { Dim::dim::<M>() }
}

impl<M: One + Zero> One for Rotmat<M>
{
  #[inline]
  fn one() -> Rotmat<M>
  { Rotmat { submat: One::one() } }
}

impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
{
  #[inline]
  fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
  { Rotmat { submat: self.submat.mul(&other.submat) } }
}

impl<V, M: RMul<V>> RMul<V> for Rotmat<M>
{
  #[inline]
  fn rmul(&self, other: &V) -> V
  { self.submat.rmul(other) }
}

impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
{
  #[inline]
  fn lmul(&self, other: &V) -> V
  { self.submat.lmul(other) }
}

impl<M: Transpose> Inv for Rotmat<M>
{
  #[inline]
  fn invert(&mut self)
  { self.transpose() }

  #[inline]
  fn inverse(&self) -> Rotmat<M>
  { self.transposed() }
}

impl<M: Transpose>
Transpose for Rotmat<M>
{
  #[inline]
  fn transposed(&self) -> Rotmat<M>
  { Rotmat { submat: self.submat.transposed() } }

  #[inline]
  fn transpose(&mut self)
  { self.submat.transpose() }
}

// we loose the info that we are a rotation matrix
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M>
{
  fn to_homogeneous(&self) -> M2
  { self.submat.to_homogeneous() }
}

impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M>
{
  #[inline]
  fn approx_epsilon() -> N
  { ApproxEq::approx_epsilon::<N, N>() }

  #[inline]
  fn approx_eq(&self, other: &Rotmat<M>) -> bool
  { self.submat.approx_eq(&other.submat) }

  #[inline]
  fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool
  { self.submat.approx_eq_eps(&other.submat, epsilon) }
}
<commit_msg>Changed the representation of rotations for 3D matrix.<commit_after>use std::num::{One, Zero};
use std::rand::{Rand, Rng, RngUtil};
use std::cmp::ApproxEq;
use traits::division_ring::DivisionRing;
use traits::rlmul::{RMul, LMul};
use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::rotation::{Rotation, Rotate, Rotatable};
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
use traits::homogeneous::ToHomogeneous;
use traits::indexable::Indexable;
use traits::norm::Norm;
use vec::Vec1;
use mat::{Mat2, Mat3};
use vec::Vec3;

#[deriving(Eq, ToStr)]
pub struct Rotmat<M>
{ priv submat: M }

pub fn rotmat2<N: Copy + Trigonometric + Neg<N>>(angle: N) -> Rotmat<Mat2<N>>
{
  let coa = angle.cos();
  let sia = angle.sin();

  Rotmat
  { submat: Mat2::new( [ copy coa, -sia, copy sia, copy coa ] ) }
}

pub fn rotmat3<N: Copy + Trigonometric + DivisionRing + Algebraic>
(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
{
  let mut axis  = axisangle;
  let angle     = axis.normalize();
  let _1        = One::one::<N>();
  let ux        = copy axis.at[0];
  let uy        = copy axis.at[1];
  let uz        = copy axis.at[2];
  let sqx       = ux * ux;
  let sqy       = uy * uy;
  let sqz       = uz * uz;
  let cos       = angle.cos();
  let one_m_cos = _1 - cos;
  let sin       = angle.sin();

  Rotmat {
    submat: Mat3::new( [
      (sqx + (_1 - sqx) * cos),
      (ux * uy * one_m_cos - uz * sin),
      (ux * uz * one_m_cos + uy * sin),

      (ux * uy * one_m_cos + uz * sin),
      (sqy + (_1 - sqy) * cos),
      (uy * uz * one_m_cos - ux * sin),

      (ux * uz * one_m_cos - uy * sin),
      (uy * uz * one_m_cos + ux * sin),
      (sqz + (_1 - sqz) * cos) ] )
  }
}

impl<N: Trigonometric + DivisionRing + Copy>
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
{
  #[inline]
  fn rotation(&self) -> Vec1<N>
  { Vec1::new([ -(self.submat.at((0, 1)) / self.submat.at((0, 0))).atan() ]) }

  #[inline]
  fn inv_rotation(&self) -> Vec1<N>
  { -self.rotation() }

  #[inline]
  fn rotate_by(&mut self, rot: &Vec1<N>)
  { *self = self.rotated(rot) }
}

impl<N: Trigonometric + DivisionRing + Copy>
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
{
  #[inline]
  fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
  { rotmat2(copy rot.at[0]) * *self }
}

impl<N: Copy + Trigonometric + DivisionRing + Algebraic>
Rotation<Vec3<N>> for Rotmat<Mat3<N>>
{
  #[inline]
  fn rotation(&self) -> Vec3<N>
  { fail!("Not yet implemented.") }
  #[inline]

  fn inv_rotation(&self) -> Vec3<N>
  { fail!("Not yet implemented.") }

  #[inline]
  fn rotate_by(&mut self, rot: &Vec3<N>)
  { *self = self.rotated(rot) }
}

impl<N: Copy + Trigonometric + DivisionRing + Algebraic>
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
{
  #[inline]
  fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
  { rotmat3(copy *axisangle) * *self }
}

impl<N: Copy + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
{
  #[inline]
  fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
  { rotmat2(rng.gen()) }
}

impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
{
  #[inline]
  fn rotate(&self, v: &V) -> V
  { self.rmul(v) }

  #[inline]
  fn inv_rotate(&self, v: &V) -> V
  { self.lmul(v) }
}

impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M>
{
  #[inline]
  fn transform_vec(&self, v: &V) -> V
  { self.rotate(v) }

  #[inline]
  fn inv_transform(&self, v: &V) -> V
  { self.inv_rotate(v) }
}

impl<N: Copy + Rand + Trigonometric + DivisionRing + Algebraic>
Rand for Rotmat<Mat3<N>>
{
  #[inline]
  fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
  { rotmat3(rng.gen()) }
}

impl<M: Dim> Dim for Rotmat<M>
{
  #[inline]
  fn dim() -> uint
  { Dim::dim::<M>() }
}

impl<M: One + Zero> One for Rotmat<M>
{
  #[inline]
  fn one() -> Rotmat<M>
  { Rotmat { submat: One::one() } }
}

impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
{
  #[inline]
  fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
  { Rotmat { submat: self.submat.mul(&other.submat) } }
}

impl<V, M: RMul<V>> RMul<V> for Rotmat<M>
{
  #[inline]
  fn rmul(&self, other: &V) -> V
  { self.submat.rmul(other) }
}

impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
{
  #[inline]
  fn lmul(&self, other: &V) -> V
  { self.submat.lmul(other) }
}

impl<M: Transpose> Inv for Rotmat<M>
{
  #[inline]
  fn invert(&mut self)
  { self.transpose() }

  #[inline]
  fn inverse(&self) -> Rotmat<M>
  { self.transposed() }
}

impl<M: Transpose>
Transpose for Rotmat<M>
{
  #[inline]
  fn transposed(&self) -> Rotmat<M>
  { Rotmat { submat: self.submat.transposed() } }

  #[inline]
  fn transpose(&mut self)
  { self.submat.transpose() }
}

// we loose the info that we are a rotation matrix
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M>
{
  fn to_homogeneous(&self) -> M2
  { self.submat.to_homogeneous() }
}

impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M>
{
  #[inline]
  fn approx_epsilon() -> N
  { ApproxEq::approx_epsilon::<N, N>() }

  #[inline]
  fn approx_eq(&self, other: &Rotmat<M>) -> bool
  { self.submat.approx_eq(&other.submat) }

  #[inline]
  fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool
  { self.submat.approx_eq_eps(&other.submat, epsilon) }
}
<|endoftext|>


<commit_before>use std::{fmt, path::Path};

use crate::RenderTarget;

#[derive(Clone, Default)]
pub struct Image {
    render_target: RenderTarget,
    source: String,
}

impl fmt::Debug for Image {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Image ( source: {})", self.source)
    }
}

impl std::cmp::PartialEq for Image {
    fn eq(&self, other: &Self) -> bool {
        self.source == other.source
    }
}

impl Image {
    /// Creates a new image with the given width and height.
    pub fn new(width: u32, height: u32) -> Self {
        Image {
            render_target: RenderTarget::new(width, height),
            source: String::default(),
        }
    }

    /// Draws a u32 slice into the image.
    pub fn draw(&mut self, data: &[u32]) {
        self.render_target.data.clone_from_slice(data);
    }

    /// Create a new image from a boxed slice of colors
    pub fn from_data(width: u32, height: u32, data: Vec<u32>) -> Result<Self, String> {
        Ok(Image {
            render_target: RenderTarget::from_data(width, height, data).unwrap(),
            source: String::new(),
        })
    }

    /// Creates a new image from an `RgbaImage`.
    pub fn from_rgba_image(image: image::RgbaImage) -> Result<Self, String> {
        let data: Vec<u32> = image
            .pixels()
            .map(|p| {
                ((p[3] as u32) << 24) | ((p[0] as u32) << 16) | ((p[1] as u32) << 8) | (p[2] as u32)
            })
            .collect();
        Self::from_data(image.width(), image.height(), data)
    }

    /// Load an image from file path. Supports BMP and PNG
    pub fn from_path<P: AsRef<Path> + std::fmt::Debug + Clone>(path: P) -> Result<Self, String> {
        let img = image::open(path.clone());

        if let Ok(img) = img {
            return Self::from_rgba_image(img.to_rgba());
        }

        Err(format!("Could not load image width path: {:?}", path))
    }

    /// Gets the width.
    pub fn width(&self) -> f64 {
        self.render_target.width() as f64
    }

    /// Gets the height.
    pub fn height(&self) -> f64 {
        self.render_target.height() as f64
    }

    pub fn data(&self) -> &[u32] {
        &self.render_target.data
    }

    pub fn data_mut(&mut self) -> &mut [u32] {
        &mut self.render_target.data
    }
}

impl From<(u32, u32, Vec<u32>)> for Image {
    fn from(image: (u32, u32, Vec<u32>)) -> Self {
        Image::from_data(image.0, image.1, image.2).unwrap()
    }
}

// --- Conversions ---

impl From<&str> for Image {
    fn from(s: &str) -> Image {
        Image::from_path(s).unwrap()
    }
}

impl From<String> for Image {
    fn from(s: String) -> Image {
        Image::from_path(s).unwrap()
    }
}

// --- Conversions ---
<commit_msg>fix windows image loading<commit_after>use std::{fmt, path::Path};

use crate::RenderTarget;

#[derive(Clone, Default)]
pub struct Image {
    render_target: RenderTarget,
    source: String,
}

impl fmt::Debug for Image {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Image ( source: {})", self.source)
    }
}

impl std::cmp::PartialEq for Image {
    fn eq(&self, other: &Self) -> bool {
        self.source == other.source
    }
}

impl Image {
    /// Creates a new image with the given width and height.
    pub fn new(width: u32, height: u32) -> Self {
        Image {
            render_target: RenderTarget::new(width, height),
            source: String::default(),
        }
    }

    /// Draws a u32 slice into the image.
    pub fn draw(&mut self, data: &[u32]) {
        self.render_target.data.clone_from_slice(data);
    }

    /// Create a new image from a boxed slice of colors
    pub fn from_data(width: u32, height: u32, data: Vec<u32>) -> Result<Self, String> {
        Ok(Image {
            render_target: RenderTarget::from_data(width, height, data).unwrap(),
            source: String::new(),
        })
    }

    /// Creates a new image from an `RgbaImage`.
    pub fn from_rgba_image(image: image::RgbaImage) -> Result<Self, String> {
        let data: Vec<u32> = image
            .pixels()
            .map(|p| {
                ((p[3] as u32) << 24) | ((p[0] as u32) << 16) | ((p[1] as u32) << 8) | (p[2] as u32)
            })
            .collect();
        Self::from_data(image.width(), image.height(), data)
    }

    /// Load an image from file path. Supports BMP and PNG
    pub fn from_path<P: AsRef<Path> + std::fmt::Debug + Clone>(path: P) -> Result<Self, String> {
        let img = image::open(path.clone());

        if let Ok(img) = img {
            return Self::from_rgba_image(img.to_rgba());
        }

        Err(format!("Could not load image width path: {:?}", path))
    }

    /// Gets the width.
    pub fn width(&self) -> f64 {
        self.render_target.width() as f64
    }

    /// Gets the height.
    pub fn height(&self) -> f64 {
        self.render_target.height() as f64
    }

    pub fn data(&self) -> &[u32] {
        &self.render_target.data
    }

    pub fn data_mut(&mut self) -> &mut [u32] {
        &mut self.render_target.data
    }
}

impl From<(u32, u32, Vec<u32>)> for Image {
    fn from(image: (u32, u32, Vec<u32>)) -> Self {
        Image::from_data(image.0, image.1, image.2).unwrap()
    }
}

pub fn os_path(path: String) -> String {
    if cfg!(windows) {
        return path.replace("/", "\\");
    } else {
        return path.replace("\\", "/");
    }
}

// --- Conversions ---

impl From<&str> for Image {
    fn from(s: &str) -> Image {
        Image::from_path(os_path(s.to_string())).unwrap()
    }
}

impl From<String> for Image {
    fn from(s: String) -> Image {
        Image::from_path(os_path(s)).unwrap()
    }
}

// --- Conversions ---
<|endoftext|>