<commit_before>//! `codec` module contains the `Package` (frame) decoding and an `tokio_core::io::Codec`
//! implementation.

use std::io::{self, Read, Write};
use uuid::Uuid;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use tokio_io::codec::{Encoder, Decoder};
use bytes::{BytesMut, BufMut};

use errors::ErrorKind;
use package::Package;
use {UsernamePassword};
use raw::RawMessage;

bitflags!{
    /// `TcpFlags` describes if optional fields (authentication) is present.
    pub flags TcpFlags: u8 {
        /// No authentication information present
        const FLAG_NONE = 0x00,
        /// Package contains authentication
        const FLAG_AUTHENTICATED = 0x01,
        //const FLAG_TRUSTED_WRITE = 0x02, // only in core
    }
}

/// Stateless simple PackageCodec
pub struct PackageCodec;

impl PackageCodec {
    fn decode_inner(&mut self, buf: &mut BytesMut) -> io::Result<Option<Package>> {
        if buf.len() < 4 + 1 + 1 + 16 {
            return Ok(None);
        }

        let len = io::Cursor::new(&buf[0..4]).read_u32::<LittleEndian>()? as usize;

        if len < 18 {
            panic!("length is too little: {}", len);
        }

        if buf.len() < len + 4 {
            return Ok(None);
        }

        let decoded_frame = self.decode_body(&buf[4..(4 + len)]);

        match decoded_frame {
            Ok((c, a, m)) => {
                buf.split_to(4 + len);
                Ok(Some(Package {
                    correlation_id: c,
                    authentication: a,
                    message: m.into(),
                }))
            }
            Err(e) => Err(e),
        }
    }

    fn decode_body(&mut self, buf: &[u8]) -> io::Result<(Uuid, Option<UsernamePassword>, RawMessage<'static>)> {
        let (d, c, a, pos) = self.decode_header(buf)?;
        let message = RawMessage::decode(d, &buf[pos..])?.into_owned();
        Ok((c, a, message))
    }

    fn decode_header(&mut self, buf: &[u8]) -> io::Result<(u8, Uuid, Option<UsernamePassword>, usize)> {
        let (d, c, a, pos) = {
            let mut cursor = io::Cursor::new(buf);
            let discriminator = cursor.read_u8()?;
            let flags = cursor.read_u8()?;
            let flags = match TcpFlags::from_bits(flags) {
                Some(flags) => flags,
                None => bail!(ErrorKind::InvalidFlags(flags)),
            };

            let correlation_id = {
                let mut uuid_bytes = [0u8; 16];
                cursor.read_exact(&mut uuid_bytes)?;
                // this should only err if len is not 16
                Uuid::from_bytes(&uuid_bytes).unwrap()
            };

            let authentication = if flags.contains(FLAG_AUTHENTICATED) {
                Some(UsernamePassword::decode(&mut cursor)?)
            } else {
                None
            };

            (discriminator, correlation_id, authentication, cursor.position() as usize)
        };

        Ok((d, c, a, pos))
    }
}

impl Decoder for PackageCodec {
    type Item = Package;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<Self::Item>> {
        self.decode_inner(buf).map_err(|e| e.into())
    }
}

impl Encoder for PackageCodec {
    type Item = Package;
    type Error = io::Error;

    fn encode(&mut self, msg: Package, buf: &mut BytesMut) -> io::Result<()> {
        // not sure how to make this without tmp vec
        let mut cursor = io::Cursor::new(Vec::new());

        let mut flags = FLAG_NONE;
        if msg.authentication.is_some() {
            flags.insert(FLAG_AUTHENTICATED);
        }

        let raw = msg.message;

        cursor.write_u32::<LittleEndian>(0)?; // placeholder for prefix
        cursor.write_u8(raw.discriminator())?;
        cursor.write_u8(flags.bits())?;
        cursor.write_all(msg.correlation_id.as_bytes())?;
        if flags.contains(FLAG_AUTHENTICATED) {
            msg.authentication
                .expect("According to flag authentication token is present")
                .encode(&mut cursor)?;
        } else {
            assert!(msg.authentication.is_none());
        }

        raw.encode(&mut cursor)?;

        let at_end = cursor.position();
        let len = at_end as u32 - 4;

        cursor.set_position(0);
        cursor.write_u32::<LittleEndian>(len)?;

        let tmp = cursor.into_inner();
        buf.put_slice(&tmp);
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::fmt::Debug;
    use rustc_serialize::hex::FromHex;
    use tokio_io::codec::{Decoder, Encoder};
    use uuid::Uuid;
    use super::{PackageCodec};
    use package::Package;
    use raw::RawMessage;
    use raw::client_messages::{WriteEventsCompleted, OperationResult};

    #[test]
    fn decode_ping() {
        test_decoding_hex("1200000003007b50a1b034b9224e8f9d708c394fab2d",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn decode_ping_with_junk() {
        test_decoding_hex("1300000003007b50a1b034b9224e8f9d708c394fab2d00",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn encode_ping() {
        test_encoding_hex("1200000003007b50a1b034b9224e8f9d708c394fab2d",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn decode_unknown_discriminator() {
        use std::borrow::Cow;

        let err = PackageCodec.decode(&mut ("12000000ff007b50a1b034b9224e8f9d708c394fab2d"
                .to_string()
                .from_hex()
                .unwrap()
                .into()))
            .unwrap() // Result
            .unwrap();// Option

        assert_eq!(err, Package {
            authentication: None,
            correlation_id: Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
            message: RawMessage::Unsupported(255, Cow::Owned(vec![])).into()
        });
    }

    #[test]
    fn decode_write_events_completed() {
        let input = "2200000083009b59d8734e9fd84eb8a421f2666a3aa40800181e20272884d6bc563084d6bc56";
        test_decoding_hex(input,
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("9b59d873-4e9f-d84e-b8a4-21f2666a3aa4").unwrap(),
                              message: RawMessage::WriteEventsCompleted(WriteEventsCompleted {
                                  result: Some(OperationResult::Success),
                                  message: None,
                                  first_event_number: 30,
                                  last_event_number: 39,
                                  prepare_position: Some(181349124),
                                  commit_position: Some(181349124)
                              }).into()
                          });
    }

    #[test]
    fn encode_write_events_completed() {
        test_encoding_hex("2200000083009b59d8734e9fd84eb8a421f2666a3aa40800181e20272884d6bc563084d6bc56",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("9b59d873-4e9f-d84e-b8a4-21f2666a3aa4").unwrap(),
                              message: RawMessage::WriteEventsCompleted(WriteEventsCompleted {
                                  result: Some(OperationResult::Success),
                                  message: None,
                                  first_event_number: 30,
                                  last_event_number: 39,
                                  prepare_position: Some(181349124),
                                  commit_position: Some(181349124)
                              }).into()
                          });

    }

    #[test]
    fn decode_authenticated_package() {
        use bytes::BytesMut;
        use auth::UsernamePassword;

        let mut buf = BytesMut::with_capacity(1024);
        let id = Uuid::new_v4();

        let msg = Package {
            correlation_id: id,
            authentication: Some(UsernamePassword::new("foobar", "abbacd")),
            message: RawMessage::Ping,
        };

        PackageCodec.encode(msg.clone(), &mut buf).unwrap();

        let decoded = PackageCodec.decode(&mut buf).unwrap().unwrap();

        assert_eq!(msg, decoded);
    }

    fn test_decoding_hex<C: Decoder>(input: &str, codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        test_decoding(input.to_string().from_hex().unwrap(), codec, expected);
    }

    fn test_decoding<C: Decoder>(input: Vec<u8>, mut codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        // decode whole buffer
        {
            let mut buf = input.clone().into();
            let item = codec.decode(&mut buf).unwrap().unwrap();

            assert_eq!(item, expected);
            assert_eq!(buf.len(), 0, "decoding correctly sized buffer left bytes");
        }

        // decoding partial buffer consumes no bytes
        for len in 1..(input.len() - 1) {
            let mut part = input.clone();
            part.truncate(len);

            let mut buf = part.into();
            assert!(codec.decode(&mut buf).unwrap().is_none());
            assert_eq!(buf.len(), len, "decoding partial buffer consumed bytes");
        }

        // decoding a too long buffer consumes no extra bytes
        {
            let mut input = input.clone();
            let len = input.len();
            input.extend(vec![0u8; len]);
            let mut buf = input.into();
            let item = codec.decode(&mut buf).unwrap().unwrap();
            assert_eq!(item, expected);
            assert_eq!(buf.len(), len, "decoding oversized buffer overused bytes");
        }
    }

    fn test_encoding_hex<C: Encoder>(input: &str, codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        test_encoding(input.to_string().from_hex().unwrap(), codec, expected);
    }

    fn test_encoding<C: Encoder>(input: Vec<u8>, mut codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        use bytes::BytesMut;

        let mut buf = BytesMut::with_capacity(input.len());
        codec.encode(expected, &mut buf).unwrap();
        assert_eq!(&buf[..],
                   &input[..],
                   "encoding did not yield same");
    }
}
<commit_msg>split encoding from requiring whole Package<commit_after>//! `codec` module contains the `Package` (frame) decoding and an `tokio_core::io::Codec`
//! implementation.

use std::io::{self, Read, Write};
use uuid::Uuid;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use tokio_io::codec::{Encoder, Decoder};
use bytes::{BytesMut, BufMut};

use errors::ErrorKind;
use package::Package;
use {UsernamePassword};
use raw::RawMessage;

bitflags!{
    /// `TcpFlags` describes if optional fields (authentication) is present.
    pub flags TcpFlags: u8 {
        /// No authentication information present
        const FLAG_NONE = 0x00,
        /// Package contains authentication
        const FLAG_AUTHENTICATED = 0x01,
        //const FLAG_TRUSTED_WRITE = 0x02, // only in core
    }
}

/// Stateless simple PackageCodec
pub struct PackageCodec;

impl PackageCodec {
    fn decode_inner(&mut self, buf: &mut BytesMut) -> io::Result<Option<Package>> {
        if buf.len() < 4 + 1 + 1 + 16 {
            return Ok(None);
        }

        let len = io::Cursor::new(&buf[0..4]).read_u32::<LittleEndian>()? as usize;

        if len < 18 {
            panic!("length is too little: {}", len);
        }

        if buf.len() < len + 4 {
            return Ok(None);
        }

        let decoded_frame = self.decode_body(&buf[4..(4 + len)]);

        match decoded_frame {
            Ok((c, a, m)) => {
                buf.split_to(4 + len);
                Ok(Some(Package {
                    correlation_id: c,
                    authentication: a,
                    message: m.into(),
                }))
            }
            Err(e) => Err(e),
        }
    }

    fn decode_body(&mut self, buf: &[u8]) -> io::Result<(Uuid, Option<UsernamePassword>, RawMessage<'static>)> {
        let (d, c, a, pos) = self.decode_header(buf)?;
        let message = RawMessage::decode(d, &buf[pos..])?.into_owned();
        Ok((c, a, message))
    }

    fn decode_header(&mut self, buf: &[u8]) -> io::Result<(u8, Uuid, Option<UsernamePassword>, usize)> {
        let (d, c, a, pos) = {
            let mut cursor = io::Cursor::new(buf);
            let discriminator = cursor.read_u8()?;
            let flags = cursor.read_u8()?;
            let flags = match TcpFlags::from_bits(flags) {
                Some(flags) => flags,
                None => bail!(ErrorKind::InvalidFlags(flags)),
            };

            let correlation_id = {
                let mut uuid_bytes = [0u8; 16];
                cursor.read_exact(&mut uuid_bytes)?;
                // this should only err if len is not 16
                Uuid::from_bytes(&uuid_bytes).unwrap()
            };

            let authentication = if flags.contains(FLAG_AUTHENTICATED) {
                Some(UsernamePassword::decode(&mut cursor)?)
            } else {
                None
            };

            (discriminator, correlation_id, authentication, cursor.position() as usize)
        };

        Ok((d, c, a, pos))
    }

    #[doc(hidden)]
    pub fn encode_parts<'a>(&self, cursor: &mut io::Cursor<Vec<u8>>, correlation_id: &Uuid, authentication: Option<&UsernamePassword>, raw: &RawMessage<'a>) -> io::Result<()> {
        let mut flags = FLAG_NONE;
        if authentication.is_some() {
            flags.insert(FLAG_AUTHENTICATED);
        }

        cursor.write_u32::<LittleEndian>(0)?; // placeholder for prefix
        cursor.write_u8(raw.discriminator())?;
        cursor.write_u8(flags.bits())?;
        cursor.write_all(correlation_id.as_bytes())?;
        if flags.contains(FLAG_AUTHENTICATED) {
            authentication
                .expect("According to flag authentication token is present")
                .encode(cursor)?;
        } else {
            assert!(authentication.is_none());
        }

        raw.encode(cursor)?;

        let at_end = cursor.position();
        let len = at_end as u32 - 4;

        cursor.set_position(0);
        cursor.write_u32::<LittleEndian>(len)?;
        Ok(())
    }
}

impl Decoder for PackageCodec {
    type Item = Package;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<Self::Item>> {
        self.decode_inner(buf).map_err(|e| e.into())
    }
}

impl Encoder for PackageCodec {
    type Item = Package;
    type Error = io::Error;

    fn encode(&mut self, msg: Package, buf: &mut BytesMut) -> io::Result<()> {
        let mut cursor = io::Cursor::new(Vec::new());

        self.encode_parts(&mut cursor, &msg.correlation_id, msg.authentication.as_ref(), &msg.message)?;

        let tmp = cursor.into_inner();
        buf.put_slice(&tmp);
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::fmt::Debug;
    use rustc_serialize::hex::FromHex;
    use tokio_io::codec::{Decoder, Encoder};
    use uuid::Uuid;
    use super::{PackageCodec};
    use package::Package;
    use raw::RawMessage;
    use raw::client_messages::{WriteEventsCompleted, OperationResult};

    #[test]
    fn decode_ping() {
        test_decoding_hex("1200000003007b50a1b034b9224e8f9d708c394fab2d",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn decode_ping_with_junk() {
        test_decoding_hex("1300000003007b50a1b034b9224e8f9d708c394fab2d00",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn encode_ping() {
        test_encoding_hex("1200000003007b50a1b034b9224e8f9d708c394fab2d",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
                              message: RawMessage::Ping.into(),
                          });
    }

    #[test]
    fn decode_unknown_discriminator() {
        use std::borrow::Cow;

        let err = PackageCodec.decode(&mut ("12000000ff007b50a1b034b9224e8f9d708c394fab2d"
                .to_string()
                .from_hex()
                .unwrap()
                .into()))
            .unwrap() // Result
            .unwrap();// Option

        assert_eq!(err, Package {
            authentication: None,
            correlation_id: Uuid::parse_str("7b50a1b0-34b9-224e-8f9d-708c394fab2d").unwrap(),
            message: RawMessage::Unsupported(255, Cow::Owned(vec![])).into()
        });
    }

    #[test]
    fn decode_write_events_completed() {
        let input = "2200000083009b59d8734e9fd84eb8a421f2666a3aa40800181e20272884d6bc563084d6bc56";
        test_decoding_hex(input,
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("9b59d873-4e9f-d84e-b8a4-21f2666a3aa4").unwrap(),
                              message: RawMessage::WriteEventsCompleted(WriteEventsCompleted {
                                  result: Some(OperationResult::Success),
                                  message: None,
                                  first_event_number: 30,
                                  last_event_number: 39,
                                  prepare_position: Some(181349124),
                                  commit_position: Some(181349124)
                              }).into()
                          });
    }

    #[test]
    fn encode_write_events_completed() {
        test_encoding_hex("2200000083009b59d8734e9fd84eb8a421f2666a3aa40800181e20272884d6bc563084d6bc56",
                          PackageCodec,
                          Package {
                              authentication: None,
                              correlation_id:
                                  Uuid::parse_str("9b59d873-4e9f-d84e-b8a4-21f2666a3aa4").unwrap(),
                              message: RawMessage::WriteEventsCompleted(WriteEventsCompleted {
                                  result: Some(OperationResult::Success),
                                  message: None,
                                  first_event_number: 30,
                                  last_event_number: 39,
                                  prepare_position: Some(181349124),
                                  commit_position: Some(181349124)
                              }).into()
                          });

    }

    #[test]
    fn decode_authenticated_package() {
        use bytes::BytesMut;
        use auth::UsernamePassword;

        let mut buf = BytesMut::with_capacity(1024);
        let id = Uuid::new_v4();

        let msg = Package {
            correlation_id: id,
            authentication: Some(UsernamePassword::new("foobar", "abbacd")),
            message: RawMessage::Ping,
        };

        PackageCodec.encode(msg.clone(), &mut buf).unwrap();

        let decoded = PackageCodec.decode(&mut buf).unwrap().unwrap();

        assert_eq!(msg, decoded);
    }

    fn test_decoding_hex<C: Decoder>(input: &str, codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        test_decoding(input.to_string().from_hex().unwrap(), codec, expected);
    }

    fn test_decoding<C: Decoder>(input: Vec<u8>, mut codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        // decode whole buffer
        {
            let mut buf = input.clone().into();
            let item = codec.decode(&mut buf).unwrap().unwrap();

            assert_eq!(item, expected);
            assert_eq!(buf.len(), 0, "decoding correctly sized buffer left bytes");
        }

        // decoding partial buffer consumes no bytes
        for len in 1..(input.len() - 1) {
            let mut part = input.clone();
            part.truncate(len);

            let mut buf = part.into();
            assert!(codec.decode(&mut buf).unwrap().is_none());
            assert_eq!(buf.len(), len, "decoding partial buffer consumed bytes");
        }

        // decoding a too long buffer consumes no extra bytes
        {
            let mut input = input.clone();
            let len = input.len();
            input.extend(vec![0u8; len]);
            let mut buf = input.into();
            let item = codec.decode(&mut buf).unwrap().unwrap();
            assert_eq!(item, expected);
            assert_eq!(buf.len(), len, "decoding oversized buffer overused bytes");
        }
    }

    fn test_encoding_hex<C: Encoder>(input: &str, codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        test_encoding(input.to_string().from_hex().unwrap(), codec, expected);
    }

    fn test_encoding<C: Encoder>(input: Vec<u8>, mut codec: C, expected: C::Item)
        where C::Item: Debug + PartialEq, C::Error: Debug
    {
        use bytes::BytesMut;

        let mut buf = BytesMut::with_capacity(input.len());
        codec.encode(expected, &mut buf).unwrap();
        assert_eq!(&buf[..],
                   &input[..],
                   "encoding did not yield same");
    }
}
<|endoftext|>


<commit_before>use cgmath::{Decomposed, Point3, Quaternion, Rad, Vector3};
use cgmath::{EuclideanSpace, InnerSpace, Rotation, Rotation3, Transform as Transform_};
use mint;
use object;

use input::{Button, Input, MOUSE_LEFT};
use node::TransformInternal;
use object::Object;

/// Simple controls for Orbital Camera.
///
/// Camera is rotating around the fixed point without any restrictions.
/// By default, it uses left mouse button as control button (hold it to rotate) and mouse wheel
/// to adjust distance to the central point.
#[derive(Clone, Debug)]
pub struct Orbit {
    object: object::Base,
    transform: TransformInternal,
    target: Point3<f32>,
    button: Button,
    speed: f32,
}

/// Helper struct to construct [`Orbit`](struct.Orbit.html) with desired settings.
#[derive(Clone, Debug)]
pub struct Builder {
    object: object::Base,
    position: mint::Point3<f32>,
    target: mint::Point3<f32>,
    button: Button,
    speed: f32,
}

impl Builder {
    /// Create new `Builder` with default values.
    pub fn new<T: Object>(object: &T) -> Self {
        Builder {
            object: object.upcast(),
            position: [0.0, 0.0, 0.0].into(),
            target: [0.0, 0.0, 0.0].into(),
            button: MOUSE_LEFT,
            speed: 1.0,
        }
    }

    /// Set the initial position.
    ///
    /// Defaults to the world origin.
    pub fn position<P>(
        &mut self,
        position: P,
    ) -> &mut Self
    where
        P: Into<mint::Point3<f32>>,
    {
        self.position = position.into();
        self
    }

    /// Set the target position.
    ///
    /// Defaults to the world origin.
    pub fn target<P>(
        &mut self,
        target: P,
    ) -> &mut Self
    where
        P: Into<mint::Point3<f32>>,
    {
        self.target = target.into();
        self
    }

    /// Setup the speed of the movements. Default value is 1.0
    pub fn speed(
        &mut self,
        speed: f32,
    ) -> &mut Self {
        self.speed = speed;
        self
    }

    /// Setup control button. Default is left mouse button (`MOUSE_LEFT`).
    pub fn button(
        &mut self,
        button: Button,
    ) -> &mut Self {
        self.button = button;
        self
    }

    /// Finalize builder and create new `OrbitControls`.
    pub fn build(&mut self) -> Orbit {
        let dir = (Point3::from(self.position) - Point3::from(self.target)).normalize();
        let up = Vector3::unit_z();
        let q = Quaternion::look_at(dir, up).invert();
        let object = self.object.clone();
        object.set_transform(self.position, q, 1.0);

        Orbit {
            object,
            transform: Decomposed {
                disp: mint::Vector3::from(self.position).into(),
                rot: q,
                scale: 1.0,
            },
            target: self.target.into(),
            button: self.button,
            speed: self.speed,
        }
    }
}

impl Orbit {
    /// Create new `Builder` with default values.
    pub fn builder<T: Object>(object: &T) -> Builder {
        Builder::new(object)
    }

    /// Update current position and rotation of the controlled object according to the last frame input.
    pub fn update(
        &mut self,
        input: &Input,
    ) {
        let mouse_delta = if input.hit(self.button) {
            input.mouse_delta_ndc()
        } else {
            [0.0, 0.0].into()
        };
        let pre = Decomposed {
            disp: -self.target.to_vec(),
            ..Decomposed::one()
        };
        let q_ver = Quaternion::from_angle_y(Rad(self.speed * (mouse_delta.x)));
        let axis = self.transform.rot * Vector3::unit_x();
        let q_hor = Quaternion::from_axis_angle(axis, Rad(self.speed * (mouse_delta.y)));
        let post = Decomposed {
            scale: 1.0 + input.mouse_wheel() / 1000.0,
            rot: q_hor * q_ver,
            disp: self.target.to_vec(),
        };
        self.transform = post.concat(&pre.concat(&self.transform));
        let pf: mint::Vector3<f32> = self.transform.disp.into();
        self.object.set_transform(pf, self.transform.rot, 1.0);
    }
}
<commit_msg>Add reset() method to Orbit<commit_after>use cgmath::{Decomposed, Point3, Quaternion, Rad, Vector3};
use cgmath::{EuclideanSpace, InnerSpace, Rotation, Rotation3, Transform as Transform_};
use mint;
use object;

use input::{Button, Input, MOUSE_LEFT};
use node::TransformInternal;
use object::Object;

/// Simple controls for Orbital Camera.
///
/// Camera is rotating around the fixed point without any restrictions.
/// By default, it uses left mouse button as control button (hold it to rotate) and mouse wheel
/// to adjust distance to the central point.
#[derive(Clone, Debug)]
pub struct Orbit {
    object: object::Base,
    transform: TransformInternal,
    initial_transform: TransformInternal,
    target: Point3<f32>,
    button: Button,
    speed: f32,
}

/// Helper struct to construct [`Orbit`](struct.Orbit.html) with desired settings.
#[derive(Clone, Debug)]
pub struct Builder {
    object: object::Base,
    position: mint::Point3<f32>,
    target: mint::Point3<f32>,
    button: Button,
    speed: f32,
}

impl Builder {
    /// Create new `Builder` with default values.
    pub fn new<T: Object>(object: &T) -> Self {
        Builder {
            object: object.upcast(),
            position: [0.0, 0.0, 0.0].into(),
            target: [0.0, 0.0, 0.0].into(),
            button: MOUSE_LEFT,
            speed: 1.0,
        }
    }

    /// Set the initial position.
    ///
    /// Defaults to the world origin.
    pub fn position<P>(
        &mut self,
        position: P,
    ) -> &mut Self
    where
        P: Into<mint::Point3<f32>>,
    {
        self.position = position.into();
        self
    }

    /// Set the target position.
    ///
    /// Defaults to the world origin.
    pub fn target<P>(
        &mut self,
        target: P,
    ) -> &mut Self
    where
        P: Into<mint::Point3<f32>>,
    {
        self.target = target.into();
        self
    }

    /// Setup the speed of the movements. Default value is 1.0
    pub fn speed(
        &mut self,
        speed: f32,
    ) -> &mut Self {
        self.speed = speed;
        self
    }

    /// Setup control button. Default is left mouse button (`MOUSE_LEFT`).
    pub fn button(
        &mut self,
        button: Button,
    ) -> &mut Self {
        self.button = button;
        self
    }

    /// Finalize builder and create new `OrbitControls`.
    pub fn build(&mut self) -> Orbit {
        let dir = (Point3::from(self.position) - Point3::from(self.target)).normalize();
        let up = Vector3::unit_z();
        let q = Quaternion::look_at(dir, up).invert();
        let object = self.object.clone();
        object.set_transform(self.position, q, 1.0);
        let transform = Decomposed {
            disp: mint::Vector3::from(self.position).into(),
            rot: q,
            scale: 1.0,
        };

        Orbit {
            object,
            transform,
            initial_transform: transform,
            target: self.target.into(),
            button: self.button,
            speed: self.speed,
        }
    }
}

impl Orbit {
    /// Create new `Builder` with default values.
    pub fn builder<T: Object>(object: &T) -> Builder {
        Builder::new(object)
    }

    /// Update current position and rotation of the controlled object according to the last frame input.
    pub fn update(
        &mut self,
        input: &Input,
    ) {
        let mouse_delta = if input.hit(self.button) {
            input.mouse_delta_ndc()
        } else {
            [0.0, 0.0].into()
        };
        let pre = Decomposed {
            disp: -self.target.to_vec(),
            ..Decomposed::one()
        };
        let q_ver = Quaternion::from_angle_y(Rad(self.speed * (mouse_delta.x)));
        let axis = self.transform.rot * Vector3::unit_x();
        let q_hor = Quaternion::from_axis_angle(axis, Rad(self.speed * (mouse_delta.y)));
        let post = Decomposed {
            scale: 1.0 + input.mouse_wheel() / 1000.0,
            rot: q_hor * q_ver,
            disp: self.target.to_vec(),
        };
        self.transform = post.concat(&pre.concat(&self.transform));
        let pf: mint::Vector3<f32> = self.transform.disp.into();
        self.object.set_transform(pf, self.transform.rot, 1.0);
    }

    /// Reset the current position and orientation of the controlled object to their initial values.
    pub fn reset(&mut self) {
        self.transform = self.initial_transform;
    }
}
<|endoftext|>


<commit_before>extern crate image;

use std::io::File;

fn main() {
    println!("24 days of Rust - image (day 12)");
    let img = image::open(&Path::new("data/in.jpg")).ok().expect("Opening image failed");
    let filtered = img.fliph();
    let out = File::create(&Path::new("out.jpg")).unwrap();
    let _ = filtered.save(out, image::JPEG).ok().expect("Saving image failed");

    let kernel = [-1.0f32, -1.0, -1.0,
                  -1.0, 8.0, -1.0,
                  -1.0, -1.0, -1.0];
    let filtered = img.filter3x3(&kernel);
    let out = File::create(&Path::new("out.jpg")).unwrap();
    let _ = filtered.save(out, image::JPEG).ok().expect("Saving image failed");
}
<commit_msg>Gaussian noise.<commit_after>extern crate image;

use image::{GenericImage, Pixel};

use std::io::File;
use std::rand;
use std::rand::distributions::{Normal, IndependentSample};

fn main() {
    println!("24 days of Rust - image (day 12)");
    let img = image::open(&Path::new("data/in.jpg")).ok().expect("Opening image failed");
    let filtered = img.fliph();
    let out = File::create(&Path::new("out.jpg")).unwrap();
    let _ = filtered.save(out, image::JPEG).ok().expect("Saving image failed");

    let kernel = [-1.0f32, -1.0, -1.0,
                  -1.0, 8.0, -1.0,
                  -1.0, -1.0, -1.0];
    let filtered = img.filter3x3(&kernel);
    let out = File::create(&Path::new("out.jpg")).unwrap();
    let _ = filtered.save(out, image::JPEG).ok().expect("Saving image failed");

    let (width, height) = img.dimensions();
    let mut rng = rand::task_rng();
    let normal = Normal::new(15.0, 15.0);
    let mut noisy = img.brighten(-25);
    for x in range(0, width) {
        for y in range(0, height) {
            let offset = normal.ind_sample(&mut rng) as u8;
            let px = img.get_pixel(x, y).map(|v| v + offset);
            noisy.put_pixel(x, y, px);
        }
    }
    let out = File::create(&Path::new("out.jpg")).unwrap();
    let _ = noisy.save(out, image::JPEG).ok().expect("Saving image failed");
}
<|endoftext|>


<commit_before>
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;

use std::collections::HashMap;

extern crate regex;
use regex::Regex;

// --------------------------------------------------------

fn main() {

	let mut my_sue_stats = HashMap::new();
	my_sue_stats.insert("children", 3);
	my_sue_stats.insert("cats", 7);
	my_sue_stats.insert("samoyeds", 2);
	my_sue_stats.insert("pomeranians", 3);
	my_sue_stats.insert("akitas", 0);
	my_sue_stats.insert("vizslas", 0);
	my_sue_stats.insert("goldfish", 5);
	my_sue_stats.insert("trees", 3);
	my_sue_stats.insert("cars", 2);
	my_sue_stats.insert("perfumes", 1);

    let path = Path::new("day16.txt");
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`
    let file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that describes the error
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(file) => file,
    };

    let reader = BufReader::new(file);
    let lines = reader.lines();

	let re = Regex::new(r"(?P<key>[:alpha:]+): (?P<value>\d+)").unwrap();

	let mut sue_num = 0;
	for line in lines {
		let text = line.unwrap();
		sue_num += 1;

		let mut has_conflict = false;
		for cap in re.captures_iter(&text) {
			let key =cap.name("key").unwrap_or("");
			let value =cap.name("value").unwrap_or("").parse::<i32>().unwrap();

			match my_sue_stats.get(&key) {
				Some(&found_value) => {
					if found_value != value {
						has_conflict = true;
					}
				},
				_ => {},
			}
		}

		if !has_conflict {
			println!("Sue {} has no conflicts", sue_num);
		}
	}
}
<commit_msg>Added day 16, part 2.<commit_after>
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;

use std::collections::HashMap;

extern crate regex;
use regex::Regex;

enum Ineq {
	Equals(i32),
	GreaterThan(i32),
	LessThan(i32),
}

// --------------------------------------------------------

fn find_sue (constraints: &HashMap<&str, Ineq>, filename: &str) -> i32 {

	let path = Path::new(filename);
    let display = path.display();

    // Open the path in read-only mode, returns `io::Result<File>`
    let file = match File::open(&path) {
        // The `description` method of `io::Error` returns a string that describes the error
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(file) => file,
    };

    let reader = BufReader::new(file);
    let lines = reader.lines();

	let re = Regex::new(r"(?P<key>[:alpha:]+): (?P<value>\d+)").unwrap();

	let mut sue_num = 0;
	let mut sue_no_conflict = -1i32;
	for line in lines {
		let text = line.unwrap();
		sue_num += 1;

		let mut has_conflict = false;
		for cap in re.captures_iter(&text) {
			let key = cap.name("key").unwrap_or("");
			let value = cap.name("value").unwrap_or("").parse::<i32>().unwrap();

			match constraints.get(&key) {
				Some(&Ineq::Equals(present_value)) => {
					if value != present_value {
						has_conflict = true;
					}
				},
				Some(&Ineq::GreaterThan(present_value)) => {
					if value <= present_value {
						has_conflict = true;
					}
				},
				Some(&Ineq::LessThan(present_value)) => {
					if value >= present_value {
						has_conflict = true;
					}
				},
				_ => {},
			}
		}

		if !has_conflict {
			println!("Sue {} has no conflicts", sue_num);
			sue_no_conflict = sue_num;
		}
	}
	sue_no_conflict
}

// --------------------------------------------------------

fn main() {

	println!("Running part 1...");
	let mut sue_stats_exact = HashMap::new();
	sue_stats_exact.insert("children", Ineq::Equals(3) );
	sue_stats_exact.insert("cats", Ineq::Equals(7) );
	sue_stats_exact.insert("samoyeds", Ineq::Equals(2) );
	sue_stats_exact.insert("pomeranians", Ineq::Equals(3) );
	sue_stats_exact.insert("akitas", Ineq::Equals(0) );
	sue_stats_exact.insert("vizslas", Ineq::Equals(0) );
	sue_stats_exact.insert("goldfish", Ineq::Equals(5) );
	sue_stats_exact.insert("trees", Ineq::Equals(3) );
	sue_stats_exact.insert("cars", Ineq::Equals(2) );
	sue_stats_exact.insert("perfumes", Ineq::Equals(1) );

	find_sue(&sue_stats_exact, "day16.txt");

	println!("Running part 2...");
	let mut sue_stats_ineq = HashMap::new();
	sue_stats_ineq.insert("children", Ineq::Equals(3) );
	sue_stats_ineq.insert("cats", Ineq::GreaterThan(7) );
	sue_stats_ineq.insert("samoyeds", Ineq::Equals(2) );
	sue_stats_ineq.insert("pomeranians", Ineq::LessThan(3) );
	sue_stats_ineq.insert("akitas", Ineq::Equals(0) );
	sue_stats_ineq.insert("vizslas", Ineq::Equals(0) );
	sue_stats_ineq.insert("goldfish", Ineq::LessThan(5) );
	sue_stats_ineq.insert("trees", Ineq::GreaterThan(3) );
	sue_stats_ineq.insert("cars", Ineq::Equals(2) );
	sue_stats_ineq.insert("perfumes", Ineq::Equals(1) );

	find_sue(&sue_stats_ineq, "day16.txt");
}
<|endoftext|>


<commit_before>use serde::de::{self, Visitor};

use super::{Deserializer, Error, Result};

pub struct IdDeserializer<'a, 'b: 'a> {
    d: &'a mut Deserializer<'b>,
}

impl<'a, 'b: 'a> IdDeserializer<'a, 'b> {
    pub fn new(d: &'a mut Deserializer<'b>) -> Self {
        IdDeserializer {
            d
        }
    }
}

impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> {
    type Error = Error;

    fn deserialize_identifier<V>(
        self,
        visitor: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        self.d.deserialize_identifier(visitor)
    }

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        self.deserialize_identifier(visitor)
    }

    fn deserialize_bool<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i8<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i16<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u8<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u16<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_f32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_f64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_char<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_str<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_string<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_bytes<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_byte_buf<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_option<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_unit<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_unit_struct<V>(
        self,
        _: &'static str,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_newtype_struct<V>(
        self,
        _: &'static str,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_seq<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_tuple<V>(
        self,
        _: usize,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_tuple_struct<V>(
        self,
        _: &'static str,
        _: usize,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_map<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_struct<V>(
        self,
        _: &'static str,
        _: &'static [&'static str],
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_enum<V>(
        self,
        _: &'static str,
        _: &'static [&'static str],
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_ignored_any<V>(
        self,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }
}
<commit_msg>impl deserialize_ignored_any for id<commit_after>use serde::de::{self, Visitor};

use super::{Deserializer, Error, Result};

pub struct IdDeserializer<'a, 'b: 'a> {
    d: &'a mut Deserializer<'b>,
}

impl<'a, 'b: 'a> IdDeserializer<'a, 'b> {
    pub fn new(d: &'a mut Deserializer<'b>) -> Self {
        IdDeserializer {
            d
        }
    }
}

impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> {
    type Error = Error;

    fn deserialize_identifier<V>(
        self,
        visitor: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        self.d.deserialize_identifier(visitor)
    }

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        self.deserialize_identifier(visitor)
    }

    fn deserialize_bool<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i8<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i16<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_i64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u8<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u16<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_u64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_f32<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_f64<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_char<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_str<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_string<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_bytes<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_byte_buf<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_option<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_unit<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_unit_struct<V>(
        self,
        _: &'static str,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_newtype_struct<V>(
        self,
        _: &'static str,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_seq<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_tuple<V>(
        self,
        _: usize,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_tuple_struct<V>(
        self,
        _: &'static str,
        _: usize,
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_map<V>(self, _: V) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_struct<V>(
        self,
        _: &'static str,
        _: &'static [&'static str],
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_enum<V>(
        self,
        _: &'static str,
        _: &'static [&'static str],
        _: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        unimplemented!("IdDeserializer may only be used for identifiers")
    }

    fn deserialize_ignored_any<V>(
        self,
        visitor: V
    ) -> Result<V::Value>
        where V: Visitor<'b>
    {
        self.deserialize_any(visitor)
    }
}
<|endoftext|>


<commit_before>use std::fmt;

use style::Style;

impl fmt::Debug for Style {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if fmt.alternate() {
            fmt.debug_struct("Style")
               .field("foreground",    &self.foreground)
               .field("background",    &self.background)
               .field("blink",         &self.is_blink)
               .field("bold",          &self.is_bold)
               .field("dimmed",        &self.is_dimmed)
               .field("hidden",        &self.is_hidden)
               .field("italic",        &self.is_italic)
               .field("reverse",       &self.is_reverse)
               .field("strikethrough", &self.is_strikethrough)
               .field("underline",     &self.is_underline)
               .finish()
        }
        else if self.is_plain() {
            fmt.write_str("Style {}")
        }
        else {
            fmt.write_str("Style { ")?;

            let mut written_anything = false;

            if let Some(fg) = self.foreground {
                if written_anything { fmt.write_str(", ")? }
                written_anything = true;
                write!(fmt, "fg({:?})", fg)?
            }

            if let Some(bg) = self.background {
                if written_anything { fmt.write_str(", ")? }
                written_anything = true;
                write!(fmt, "on({:?})", bg)?
            }

            {
                let mut write_flag = |name| {
                    if written_anything { fmt.write_str(", ")? }
                    written_anything = true;
                    fmt.write_str(name)
                };

                if self.is_blink          { write_flag("blink")? }
                if self.is_bold           { write_flag("bold")? }
                if self.is_dimmed         { write_flag("dimmed")? }
                if self.is_hidden         { write_flag("hidden")? }
                if self.is_italic         { write_flag("italic")? }
                if self.is_reverse        { write_flag("reverse")? }
                if self.is_strikethrough  { write_flag("strikethrough")? }
                if self.is_underline      { write_flag("underline")? }
            }

            write!(fmt, " }}")
        }
    }
}

#[cfg(test)]
mod test {
    use style::Colour::*;
    use style::Style;

    fn style() -> Style {
        Style::new()
    }

    macro_rules! test {
        ($name: ident: $obj: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, format!("{:?}", $obj));
            }
        };
    }

    test!(empty:   style()                  => "Style {}");
    test!(bold:    style().bold()           => "Style { bold }");
    test!(italic:  style().italic()         => "Style { italic }");
    test!(both:    style().bold().italic()  => "Style { bold, italic }");

    test!(red:     Red.normal()                     => "Style { fg(Red) }");
    test!(redblue: Red.normal().on(RGB(3, 2, 4))    => "Style { fg(Red), on(RGB(3, 2, 4)) }");

    test!(everything:
            Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() =>
            "Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }");

    #[test]
    fn long_and_detailed() {
        let debug = r##"Style {
    foreground: Some(
        Blue
    ),
    background: None,
    blink: false,
    bold: true,
    dimmed: false,
    hidden: false,
    italic: false,
    reverse: false,
    strikethrough: false,
    underline: false
}"##;
        assert_eq!(debug, format!("{:#?}", Blue.bold()));
    }
}
<commit_msg>Document the Debug implementation<commit_after>use std::fmt;

use style::Style;

/// Styles have a special `Debug` implementation that only shows the fields that
/// are set. Fields that haven’t been touched aren’t included in the output.
///
/// This behaviour gets bypassed when using the alternate formatting mode
/// `format!("{:#?}")`.
///
///     use ansi_term::Colour::{Red, Blue};
///     assert_eq!("Style { fg(Red), on(Blue), bold, italic }",
///                format!("{:?}", Red.on(Blue).bold().italic()));
impl fmt::Debug for Style {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if fmt.alternate() {
            fmt.debug_struct("Style")
               .field("foreground",    &self.foreground)
               .field("background",    &self.background)
               .field("blink",         &self.is_blink)
               .field("bold",          &self.is_bold)
               .field("dimmed",        &self.is_dimmed)
               .field("hidden",        &self.is_hidden)
               .field("italic",        &self.is_italic)
               .field("reverse",       &self.is_reverse)
               .field("strikethrough", &self.is_strikethrough)
               .field("underline",     &self.is_underline)
               .finish()
        }
        else if self.is_plain() {
            fmt.write_str("Style {}")
        }
        else {
            fmt.write_str("Style { ")?;

            let mut written_anything = false;

            if let Some(fg) = self.foreground {
                if written_anything { fmt.write_str(", ")? }
                written_anything = true;
                write!(fmt, "fg({:?})", fg)?
            }

            if let Some(bg) = self.background {
                if written_anything { fmt.write_str(", ")? }
                written_anything = true;
                write!(fmt, "on({:?})", bg)?
            }

            {
                let mut write_flag = |name| {
                    if written_anything { fmt.write_str(", ")? }
                    written_anything = true;
                    fmt.write_str(name)
                };

                if self.is_blink          { write_flag("blink")? }
                if self.is_bold           { write_flag("bold")? }
                if self.is_dimmed         { write_flag("dimmed")? }
                if self.is_hidden         { write_flag("hidden")? }
                if self.is_italic         { write_flag("italic")? }
                if self.is_reverse        { write_flag("reverse")? }
                if self.is_strikethrough  { write_flag("strikethrough")? }
                if self.is_underline      { write_flag("underline")? }
            }

            write!(fmt, " }}")
        }
    }
}

#[cfg(test)]
mod test {
    use style::Colour::*;
    use style::Style;

    fn style() -> Style {
        Style::new()
    }

    macro_rules! test {
        ($name: ident: $obj: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, format!("{:?}", $obj));
            }
        };
    }

    test!(empty:   style()                  => "Style {}");
    test!(bold:    style().bold()           => "Style { bold }");
    test!(italic:  style().italic()         => "Style { italic }");
    test!(both:    style().bold().italic()  => "Style { bold, italic }");

    test!(red:     Red.normal()                     => "Style { fg(Red) }");
    test!(redblue: Red.normal().on(RGB(3, 2, 4))    => "Style { fg(Red), on(RGB(3, 2, 4)) }");

    test!(everything:
            Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() =>
            "Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }");

    #[test]
    fn long_and_detailed() {
        let debug = r##"Style {
    foreground: Some(
        Blue
    ),
    background: None,
    blink: false,
    bold: true,
    dimmed: false,
    hidden: false,
    italic: false,
    reverse: false,
    strikethrough: false,
    underline: false
}"##;
        assert_eq!(debug, format!("{:#?}", Blue.bold()));
    }
}
<|endoftext|>


<commit_before>use rug::ops::Pow;
use rug::Integer;
use std::ops::Div;
// use std::ops::{Add, Neg, Sub};

use euclid::*;

use defs::*;
use math;

// A "vector" in the world, possibly going up or down levels
// TODO: Do we need a `Dyadic`?

#[derive(Clone, Debug, PartialEq, Eq)] // MUST TODO: this Eq is dangerous!
pub struct Delta {
    pub zdelta: i16,
    pub scale: i16,
    pub coords: TypedVector2D<Integer, UniverseSpace>,
    // So a coord distance of 1 means a `real` distance of 2^(scale) at z value 0
}

impl Delta {
    pub fn zero() -> Delta {
        Delta {
            zdelta: 0,
            scale: 0,
            coords: TypedVector2D::new(Integer::new(), Integer::new()),
        }
    }

    pub fn append(&self, other: &Delta) -> Delta {
        let zdelta = self.zdelta + other.zdelta;
        let other_relative_scale = self.zdelta + other.scale;
        let newscale = self.scale.min(other_relative_scale);

        let newcoords: TypedVector2D<Integer, UniverseSpace>;
        if self.scale == other_relative_scale {
            newcoords = math::add_vec(self.coords.clone(), other.coords.clone());
        } else if self.scale >= other_relative_scale {
            let difference = (self.scale - other_relative_scale) as u32;
            newcoords = math::add_vec(
                math::scale_vec(&self.coords, &Integer::from(ZOOM_SCALE).pow(difference)),
                other.coords.clone(),
            );
        } else {
            let difference = (other_relative_scale - self.scale) as u32;
            newcoords = math::add_vec(
                math::scale_vec(&other.coords, &Integer::from(ZOOM_SCALE).pow(difference)),
                self.coords.clone(),
            );
        }

        Delta {
            zdelta: zdelta,
            scale: newscale,
            coords: newcoords,
        }
    }

    pub fn invert(&self) -> Delta {
        Delta {
            zdelta: -self.zdelta,
            scale: self.scale - self.zdelta,
            coords: TypedVector2D::new(-self.coords.x.clone(), -self.coords.y.clone()),
        }
    }

    pub fn revert(&self, other: &Delta) -> Delta {
        self.append(&other.invert())
    }

    // pub fn truncate(&self) -> Delta {
    //     if self.scale == self.zdelta {
    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: self.coords.clone(),
    //         }
    //     } else if self.scale > self.zdelta {
    //         let difference = (self.scale - self.zdelta) as u32;
    //         let newcoords =
    //             math::scale_vec(&self.coords, Integer::from(ZOOM_SCALE).pow(difference));

    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: newcoords,
    //         }
    //     } else {
    //         let difference = (self.zdelta - self.scale) as u32;
    //         let truncated_coords_x = self.coords.x.clone() >> difference;
    //         let truncated_coords_y = self.coords.y.clone() >> difference;
    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: TypedVector2D::new(truncated_coords_x, truncated_coords_y),
    //         }
    //     }
    // }

    pub fn to_scaled_fvec(&self) -> TypedVector2D<f32, UniverseSpace> {
        TypedVector2D::new(
            math::scaled_bigint_to_float(&self.coords.x, self.scale),
            math::scaled_bigint_to_float(&self.coords.y, self.scale),
        )
    }

    pub fn to_scale_transform(&self) -> TypedTransform2D<f32, UniverseSpace, UniverseSpace> {
        let scale = (ZOOM_SCALE as f32).powi(self.zdelta as i32);
        TypedTransform2D::identity()
            .post_scale(scale, scale)
            .post_translate(self.to_scaled_fvec())
    }

    pub fn normalize(&self) -> Delta {
        if self.coords.x == 0 && self.coords.y == 0 {
            return Delta {
                coords: TypedVector2D::new(Integer::new(), Integer::new()),
                scale: 0,
                zdelta: self.zdelta,
            };
        }

        let mut result = self.clone();

        while result.coords.x.is_divisible_2pow(1) && result.coords.x.is_divisible_2pow(1) {
            result.coords.x = result.coords.x.div(2);
            result.coords.y = result.coords.y.div(2);
            result.scale += 1;
        }

        return result;
    }

    pub fn to_uvec(&self) -> Option<UVec> {
        let normalized = self.normalize();

        assert!(normalized.zdelta == 0);
        assert!(normalized.scale >= 0);

        Some(
            UVec::new(
                normalized.coords.x.to_i32().unwrap(),
                normalized.coords.y.to_i32().unwrap(),
            ) * ZOOM_SCALE.pow(normalized.scale as u32) as i32,
        )
    }
}

impl<U> From<TypedVector2D<f32, U>> for Delta
where
    U: SpaceWithLevel,
{
    fn from(c: TypedVector2D<f32, U>) -> Delta {
        let int_x = (c.x * (ZOOM_SCALE as f32).pow(FRACTIONAL_DELTA_SCALE as i32)) as i32;
        let int_y = (c.y * (ZOOM_SCALE as f32).pow(FRACTIONAL_DELTA_SCALE as i32)) as i32;

        Delta {
            zdelta: U::LEVEL,
            scale: U::LEVEL - FRACTIONAL_DELTA_SCALE as i16,
            coords: TypedVector2D::new(Integer::from(int_x), Integer::from(int_y)),
        }
    }
}

impl<U> From<TypedVector2D<i32, U>> for Delta
where
    U: SpaceWithLevel,
{
    fn from(c: TypedVector2D<i32, U>) -> Delta {
        Delta {
            zdelta: U::LEVEL,
            scale: U::LEVEL,
            coords: TypedVector2D::new(Integer::from(c.x), Integer::from(c.y)),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn fractional_append_1() {
        let a = Delta {
            zdelta: 2,
            scale: 1,
            coords: TypedVector2D::new(Integer::from(-1), Integer::from(0)),
        };
        let b = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(1), Integer::from(0)),
        };

        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: 1,
                scale: 1,
                coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
            }
        );
    }

    #[test]
    fn fractional_append_2() {
        let a = Delta {
            zdelta: 1,
            scale: 0,
            coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
        };

        let b = Delta {
            zdelta: 1,
            scale: 1,
            coords: TypedVector2D::new(Integer::from(-1), Integer::from(0)),
        };
        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: 2,
                scale: 0,
                coords: TypedVector2D::new(Integer::from(-4), Integer::from(0)),
            }
        );
    }

    #[test]
    fn fractional_append_3() {
        let a = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(1), Integer::from(0)),
        };

        let b = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
        };
        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: -2,
                scale: -2,
                coords: TypedVector2D::new(Integer::from(2), Integer::from(0)),
            }
        );
    }

}
<commit_msg>Fix humiliating copy paste error<commit_after>use rug::ops::Pow;
use rug::Integer;
use std::ops::Div;
// use std::ops::{Add, Neg, Sub};

use euclid::*;

use defs::*;
use math;

// A "vector" in the world, possibly going up or down levels
// TODO: Do we need a `Dyadic`?

#[derive(Clone, Debug, PartialEq, Eq)] // MUST TODO: this Eq is dangerous!
pub struct Delta {
    pub zdelta: i16,
    pub scale: i16,
    pub coords: TypedVector2D<Integer, UniverseSpace>,
    // So a coord distance of 1 means a `real` distance of 2^(scale) at z value 0
}

impl Delta {
    pub fn zero() -> Delta {
        Delta {
            zdelta: 0,
            scale: 0,
            coords: TypedVector2D::new(Integer::new(), Integer::new()),
        }
    }

    pub fn append(&self, other: &Delta) -> Delta {
        let zdelta = self.zdelta + other.zdelta;
        let other_relative_scale = self.zdelta + other.scale;
        let newscale = self.scale.min(other_relative_scale);

        let newcoords: TypedVector2D<Integer, UniverseSpace>;
        if self.scale == other_relative_scale {
            newcoords = math::add_vec(self.coords.clone(), other.coords.clone());
        } else if self.scale >= other_relative_scale {
            let difference = (self.scale - other_relative_scale) as u32;
            newcoords = math::add_vec(
                math::scale_vec(&self.coords, &Integer::from(ZOOM_SCALE).pow(difference)),
                other.coords.clone(),
            );
        } else {
            let difference = (other_relative_scale - self.scale) as u32;
            newcoords = math::add_vec(
                math::scale_vec(&other.coords, &Integer::from(ZOOM_SCALE).pow(difference)),
                self.coords.clone(),
            );
        }

        Delta {
            zdelta: zdelta,
            scale: newscale,
            coords: newcoords,
        }
    }

    pub fn invert(&self) -> Delta {
        Delta {
            zdelta: -self.zdelta,
            scale: self.scale - self.zdelta,
            coords: TypedVector2D::new(-self.coords.x.clone(), -self.coords.y.clone()),
        }
    }

    pub fn revert(&self, other: &Delta) -> Delta {
        self.append(&other.invert())
    }

    // pub fn truncate(&self) -> Delta {
    //     if self.scale == self.zdelta {
    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: self.coords.clone(),
    //         }
    //     } else if self.scale > self.zdelta {
    //         let difference = (self.scale - self.zdelta) as u32;
    //         let newcoords =
    //             math::scale_vec(&self.coords, Integer::from(ZOOM_SCALE).pow(difference));

    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: newcoords,
    //         }
    //     } else {
    //         let difference = (self.zdelta - self.scale) as u32;
    //         let truncated_coords_x = self.coords.x.clone() >> difference;
    //         let truncated_coords_y = self.coords.y.clone() >> difference;
    //         Delta {
    //             zdelta: self.zdelta,
    //             coords: TypedVector2D::new(truncated_coords_x, truncated_coords_y),
    //         }
    //     }
    // }

    pub fn to_scaled_fvec(&self) -> TypedVector2D<f32, UniverseSpace> {
        TypedVector2D::new(
            math::scaled_bigint_to_float(&self.coords.x, self.scale),
            math::scaled_bigint_to_float(&self.coords.y, self.scale),
        )
    }

    pub fn to_scale_transform(&self) -> TypedTransform2D<f32, UniverseSpace, UniverseSpace> {
        let scale = (ZOOM_SCALE as f32).powi(self.zdelta as i32);
        TypedTransform2D::identity()
            .post_scale(scale, scale)
            .post_translate(self.to_scaled_fvec())
    }

    pub fn normalize(&self) -> Delta {
        if self.coords.x == 0 && self.coords.y == 0 {
            return Delta {
                coords: TypedVector2D::new(Integer::new(), Integer::new()),
                scale: 0,
                zdelta: self.zdelta,
            };
        }

        let mut result = self.clone();

        while result.coords.x.is_divisible_2pow(1) && result.coords.y.is_divisible_2pow(1) {
            result.coords.x = result.coords.x.div(2);
            result.coords.y = result.coords.y.div(2);
            result.scale += 1;
        }

        return result;
    }

    pub fn to_uvec(&self) -> Option<UVec> {
        let normalized = self.normalize();

        assert!(normalized.zdelta == 0);
        assert!(normalized.scale >= 0);

        Some(
            UVec::new(
                normalized.coords.x.to_i32().unwrap(),
                normalized.coords.y.to_i32().unwrap(),
            ) * ZOOM_SCALE.pow(normalized.scale as u32) as i32,
        )
    }
}

impl<U> From<TypedVector2D<f32, U>> for Delta
where
    U: SpaceWithLevel,
{
    fn from(c: TypedVector2D<f32, U>) -> Delta {
        let int_x = (c.x * (ZOOM_SCALE as f32).pow(FRACTIONAL_DELTA_SCALE as i32)) as i32;
        let int_y = (c.y * (ZOOM_SCALE as f32).pow(FRACTIONAL_DELTA_SCALE as i32)) as i32;

        Delta {
            zdelta: U::LEVEL,
            scale: U::LEVEL - FRACTIONAL_DELTA_SCALE as i16,
            coords: TypedVector2D::new(Integer::from(int_x), Integer::from(int_y)),
        }
    }
}

impl<U> From<TypedVector2D<i32, U>> for Delta
where
    U: SpaceWithLevel,
{
    fn from(c: TypedVector2D<i32, U>) -> Delta {
        Delta {
            zdelta: U::LEVEL,
            scale: U::LEVEL,
            coords: TypedVector2D::new(Integer::from(c.x), Integer::from(c.y)),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn fractional_append_1() {
        let a = Delta {
            zdelta: 2,
            scale: 1,
            coords: TypedVector2D::new(Integer::from(-1), Integer::from(0)),
        };
        let b = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(1), Integer::from(0)),
        };

        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: 1,
                scale: 1,
                coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
            }
        );
    }

    #[test]
    fn fractional_append_2() {
        let a = Delta {
            zdelta: 1,
            scale: 0,
            coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
        };

        let b = Delta {
            zdelta: 1,
            scale: 1,
            coords: TypedVector2D::new(Integer::from(-1), Integer::from(0)),
        };
        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: 2,
                scale: 0,
                coords: TypedVector2D::new(Integer::from(-4), Integer::from(0)),
            }
        );
    }

    #[test]
    fn fractional_append_3() {
        let a = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(1), Integer::from(0)),
        };

        let b = Delta {
            zdelta: -1,
            scale: -1,
            coords: TypedVector2D::new(Integer::from(0), Integer::from(0)),
        };
        assert_eq!(
            a.append(&b),
            Delta {
                zdelta: -2,
                scale: -2,
                coords: TypedVector2D::new(Integer::from(2), Integer::from(0)),
            }
        );
    }

}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<commit_msg>update unittests<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }

    /// Convert a Tensor to a TensorHandle for use in eager execution.
    pub fn into_handle<'a>(self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        self.freeze().to_handle(ctx)
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();

        // Create a read-only tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        // Create a TensorHandle directly from a Tensor.
        // It takes ownership of the Tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.into_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[test]
    fn handle_to_handle_unsafe() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        let mut tensor2 = unsafe {tensor2.into_tensor()};
        assert_eq!(tensor, tensor2);

        // Check that tensor and tensro2 share the same underlying data.
        // This is why we need to use unsafe.
        tensor2[0] = 5;
        assert_eq!(tensor[0], 5);
    }
}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

/// Simple helper trait to convert a Tensor into a TensorHandle for use in eager
/// execution.
pub trait ToTensorHandle<'a> {
    /// Convert the Tensor or TensorHandle into a new TensorHandle.
    ///
    /// _Warning_ : This function may create multiple handles to the same
    /// underlying tensor. Users should be careful not to modify the tensor
    /// after converting it to a handle. Also, users should be careful not
    /// to modify the tensor obtained via the TensorHandle's `resolve` method.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for Tensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for T {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[]);
        tensor[0] = self.clone();
        TensorHandle::new(ctx, &tensor)
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for [T] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[self.len() as u64]);
        for (e, v) in tensor.iter_mut().zip(self) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2: Tensor<i32> = handle2.resolve().unwrap();
        assert_eq!(&tensor[..], &tensor2[..]);
    }

    #[test]
    fn tensortype_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = 1i32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1i64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);
    }

    #[test]
    fn tarray_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = [1i32, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1i64, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f32, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f64, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);
    }
}
<commit_msg>add trait impl for ndarray<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

#[cfg(feature = "ndarray")]
use ndarray::{ArrayBase, Data, Dimension};

/// Simple helper trait to convert a Tensor into a TensorHandle for use in eager
/// execution.
pub trait ToTensorHandle<'a> {
    /// Convert the Tensor or TensorHandle into a new TensorHandle.
    ///
    /// _Warning_ : This function may create multiple handles to the same
    /// underlying tensor. Users should be careful not to modify the tensor
    /// after converting it to a handle. Also, users should be careful not
    /// to modify the tensor obtained via the TensorHandle's `resolve` method.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for Tensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for T {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[]);
        tensor[0] = self.clone();
        TensorHandle::new(ctx, &tensor)
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for [T] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[self.len() as u64]);
        for (e, v) in tensor.iter_mut().zip(self) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}

#[cfg(feature = "ndarray")]
/// Convert any ndarray::ArrayBase type into a TensorHandle
impl<'a, T, S, D> ToTensorHandle<'a> for ArrayBase<S, D>
where
    T: TensorType,
    S: Data<Elem = T>,
    D: Dimension,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let dims: Vec<u64> = self.shape().iter().map(|x| *x as u64).collect();
        let mut tensor: Tensor<T> = Tensor::new(&dims);
        for (e, v) in tensor.iter_mut().zip(self.iter()) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2: Tensor<i32> = handle2.resolve().unwrap();
        assert_eq!(&tensor[..], &tensor2[..]);
    }

    #[test]
    fn tensortype_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = 1i32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1i64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);
    }

    #[test]
    fn tarray_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = [1i32, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1i64, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f32, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f64, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    ///
    /// _Warning_ : This function may create multiple handles to the same
    /// underlying tensor. Users should be careful not to modify the tensor
    /// after converting it to a TensorHandle. Also, users should be careful
    /// not to modify the Tensor generated from the TensorHandle's `resolve`
    /// method.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<commit_msg>update ToTensorHandle doc<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<|endoftext|>