<commit_before>//! This crate connects Rust MessagePack library with [`serde`][serde] providing an ability to
//! easily serialize and deserialize both Rust built-in types, the standard library and custom data
//! structures.
//!
//! ## Motivating example
//!
//! ```
//! let buf = rmp_serde::to_vec(&(42, "the Answer")).unwrap();
//!
//! assert_eq!(
//!     vec![0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72],
//!     buf
//! );
//!
//! assert_eq!((42, "the Answer"), rmp_serde::from_read_ref(&buf).unwrap());
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from MessagePack via the serialization API.
//!
//! To be able to serialize a piece of data, it must implement the `serde::Serialize` trait. To be
//! able to deserialize a piece of data, it must implement the `serde::Deserialize` trait. Serde
//! provides an annotation to automatically generate the code for these
//! traits: `#[derive(Serialize, Deserialize)]`.
//!
//! # Examples
//!
//! ```
//! extern crate serde;
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate rmp_serde as rmps;
//!
//! use std::collections::HashMap;
//! use serde::{Deserialize, Serialize};
//! use rmps::{Deserializer, Serializer};
//!
//! #[derive(Debug, PartialEq, Deserialize, Serialize)]
//! struct Human {
//!     age: u32,
//!     name: String,
//! }
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = Human {
//!         age: 42,
//!         name: "John".into(),
//!     };
//!
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//! }
//! ```
//!
//! [serde]: https://serde.rs/

#![warn(missing_debug_implementations, missing_docs)]

#[macro_use]
extern crate serde;

use std::fmt::{self, Display, Formatter};
use std::mem;
use std::str::{self, Utf8Error};

use serde::de;
use serde::{Deserialize, Serialize};

pub use crate::decode::{from_read, from_read_ref, Deserializer};
pub use crate::encode::{to_vec, to_vec_named, Serializer};

pub use crate::decode::from_slice;

pub mod config;
pub mod decode;
pub mod encode;

/// Name of Serde newtype struct to Represent Msgpack's Ext
/// Msgpack Ext: Ext(tag, binary)
/// Serde data model: _ExtStruct((tag, binary))
/// Example Serde impl for custom type:
///
/// ```ignore
/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
/// #[serde(rename = "_ExtStruct")]
/// struct ExtStruct((i8, serde_bytes::ByteBuf));
///
/// test_round(ExtStruct((2, serde_bytes::ByteBuf::from(vec![5]))),
///            Value::Ext(2, vec![5]));
/// ```
pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";

/// Helper that allows both to encode and decode strings no matter whether they contain valid or
/// invalid UTF-8.
///
/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
#[derive(Clone, Debug, PartialEq)]
pub struct Raw {
    s: Result<String, (Vec<u8>, Utf8Error)>,
}

impl Raw {
    /// Constructs a new `Raw` from the UTF-8 string.
    #[inline]
    pub fn new(v: String) -> Self {
        Self { s: Ok(v) }
    }

    /// Converts a vector of bytes to a `Raw`.
    pub fn from_utf8(v: Vec<u8>) -> Self {
        match String::from_utf8(v) {
            Ok(v) => Raw::new(v),
            Err(err) => {
                let e = err.utf8_error();
                Self {
                    s: Err((err.into_bytes(), e)),
                }
            }
        }
    }

    /// Returns `true` if the raw is valid UTF-8.
    #[inline]
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    #[inline]
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s.as_str()),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
    /// else `None`.
    #[inline]
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((_, ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }

    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn into_str(self) -> Option<String> {
        self.s.ok()
    }

    /// Converts a `Raw` into a byte vector.
    #[inline]
    pub fn into_bytes(self) -> Vec<u8> {
        match self.s {
            Ok(s) => s.into_bytes(),
            Err(err) => err.0,
        }
    }
}

impl Serialize for Raw {
    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer
    {
        let s = match self.s {
            Ok(ref s) => s.as_str(),
            Err((ref b, ..)) => unsafe { mem::transmute(&b[..]) },
        };

        se.serialize_str(s)
    }
}

struct RawVisitor;

impl<'de> de::Visitor<'de> for RawVisitor {
    type Value = Raw;

    #[cold]
    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
        Ok(Raw { s: Ok(v) })
    }

    #[inline]
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(Raw { s: Ok(v.into()) })
    }

    #[inline]
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s.into()),
            Err(err) => Err((v.into(), err)),
        };

        Ok(Raw { s })
    }

    #[inline]
    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match String::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => {
                let e = err.utf8_error();
                Err((err.into_bytes(), e))
            }
        };

        Ok(Raw { s })
    }
}

impl<'de> Deserialize<'de> for Raw {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer<'de>
    {
        de.deserialize_any(RawVisitor)
    }
}

/// Helper that allows both to encode and decode strings no matter whether they contain valid or
/// invalid UTF-8.
///
/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RawRef<'a> {
    s: Result<&'a str, (&'a [u8], Utf8Error)>,
}

impl<'a> RawRef<'a> {
    /// Constructs a new `RawRef` from the UTF-8 string.
    #[inline]
    pub fn new(v: &'a str) -> Self {
        Self { s: Ok(v) }
    }

    /// Converts a vector of bytes to a `RawRef`.
    pub fn from_utf8(v: &'a [u8]) -> Self {
        match str::from_utf8(v) {
            Ok(v) => RawRef::new(v),
            Err(err) => {
                Self {
                    s: Err((v, err))
                }
            }
        }
    }

    /// Returns `true` if the raw is valid UTF-8.
    #[inline]
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    #[inline]
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
    /// else `None`.
    #[inline]
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((_, ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }
}

impl<'a> Serialize for RawRef<'a> {
    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = match self.s {
            Ok(ref s) => s,
            Err((ref b, ..)) => unsafe { mem::transmute(b) },
        };

        se.serialize_str(s)
    }
}

struct RawRefVisitor;

impl<'de> de::Visitor<'de> for RawRefVisitor {
    type Value = RawRef<'de>;

    #[cold]
    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(RawRef { s: Ok(v) })
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => Err((v, err)),
        };

        Ok(RawRef { s })
    }
}

impl<'de> Deserialize<'de> for RawRef<'de> {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer<'de>
    {
        de.deserialize_any(RawRefVisitor)
    }
}
<commit_msg>Deprecate unsound RawRef newtype<commit_after>//! This crate connects Rust MessagePack library with [`serde`][serde] providing an ability to
//! easily serialize and deserialize both Rust built-in types, the standard library and custom data
//! structures.
//!
//! ## Motivating example
//!
//! ```
//! let buf = rmp_serde::to_vec(&(42, "the Answer")).unwrap();
//!
//! assert_eq!(
//!     vec![0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72],
//!     buf
//! );
//!
//! assert_eq!((42, "the Answer"), rmp_serde::from_read_ref(&buf).unwrap());
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from MessagePack via the serialization API.
//!
//! To be able to serialize a piece of data, it must implement the `serde::Serialize` trait. To be
//! able to deserialize a piece of data, it must implement the `serde::Deserialize` trait. Serde
//! provides an annotation to automatically generate the code for these
//! traits: `#[derive(Serialize, Deserialize)]`.
//!
//! # Examples
//!
//! ```
//! extern crate serde;
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate rmp_serde as rmps;
//!
//! use std::collections::HashMap;
//! use serde::{Deserialize, Serialize};
//! use rmps::{Deserializer, Serializer};
//!
//! #[derive(Debug, PartialEq, Deserialize, Serialize)]
//! struct Human {
//!     age: u32,
//!     name: String,
//! }
//!
//! fn main() {
//!     let mut buf = Vec::new();
//!     let val = Human {
//!         age: 42,
//!         name: "John".into(),
//!     };
//!
//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
//! }
//! ```
//!
//! [serde]: https://serde.rs/

#![warn(missing_debug_implementations, missing_docs)]

#[macro_use]
extern crate serde;

use std::fmt::{self, Display, Formatter};
use std::mem;
use std::str::{self, Utf8Error};

use serde::de;
use serde::{Deserialize, Serialize};

pub use crate::decode::{from_read, from_read_ref, Deserializer};
pub use crate::encode::{to_vec, to_vec_named, Serializer};

pub use crate::decode::from_slice;

pub mod config;
pub mod decode;
pub mod encode;

/// Name of Serde newtype struct to Represent Msgpack's Ext
/// Msgpack Ext: Ext(tag, binary)
/// Serde data model: _ExtStruct((tag, binary))
/// Example Serde impl for custom type:
///
/// ```ignore
/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
/// #[serde(rename = "_ExtStruct")]
/// struct ExtStruct((i8, serde_bytes::ByteBuf));
///
/// test_round(ExtStruct((2, serde_bytes::ByteBuf::from(vec![5]))),
///            Value::Ext(2, vec![5]));
/// ```
pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";

/// Helper that allows both to encode and decode strings no matter whether they contain valid or
/// invalid UTF-8.
///
/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
#[derive(Clone, Debug, PartialEq)]
pub struct Raw {
    s: Result<String, (Vec<u8>, Utf8Error)>,
}

impl Raw {
    /// Constructs a new `Raw` from the UTF-8 string.
    #[inline]
    pub fn new(v: String) -> Self {
        Self { s: Ok(v) }
    }

    /// DO NOT USE. See <https://github.com/3Hren/msgpack-rust/issues/305>
    #[deprecated(note = "This implementation is unsound and dangerous. See https://github.com/3Hren/msgpack-rust/issues/305")]
    pub fn from_utf8(v: Vec<u8>) -> Self {
        match String::from_utf8(v) {
            Ok(v) => Raw::new(v),
            Err(err) => {
                let e = err.utf8_error();
                Self {
                    s: Err((err.into_bytes(), e)),
                }
            }
        }
    }

    /// Returns `true` if the raw is valid UTF-8.
    #[inline]
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    #[inline]
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s.as_str()),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
    /// else `None`.
    #[inline]
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((_, ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }

    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn into_str(self) -> Option<String> {
        self.s.ok()
    }

    /// Converts a `Raw` into a byte vector.
    #[inline]
    pub fn into_bytes(self) -> Vec<u8> {
        match self.s {
            Ok(s) => s.into_bytes(),
            Err(err) => err.0,
        }
    }
}

impl Serialize for Raw {
    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer
    {
        let s = match self.s {
            Ok(ref s) => s.as_str(),
            // FIXME: this is invalid. It should use a newtype hack instead.
            // https://github.com/3Hren/msgpack-rust/issues/305
            Err((ref b, ..)) => unsafe { mem::transmute(&b[..]) },
        };

        se.serialize_str(s)
    }
}

struct RawVisitor;

impl<'de> de::Visitor<'de> for RawVisitor {
    type Value = Raw;

    #[cold]
    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
        Ok(Raw { s: Ok(v) })
    }

    #[inline]
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(Raw { s: Ok(v.into()) })
    }

    #[inline]
    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s.into()),
            Err(err) => Err((v.into(), err)),
        };

        Ok(Raw { s })
    }

    #[inline]
    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match String::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => {
                let e = err.utf8_error();
                Err((err.into_bytes(), e))
            }
        };

        Ok(Raw { s })
    }
}

impl<'de> Deserialize<'de> for Raw {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer<'de>
    {
        de.deserialize_any(RawVisitor)
    }
}

/// Helper that allows both to encode and decode strings no matter whether they contain valid or
/// invalid UTF-8.
///
/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RawRef<'a> {
    s: Result<&'a str, (&'a [u8], Utf8Error)>,
}

impl<'a> RawRef<'a> {
    /// Constructs a new `RawRef` from the UTF-8 string.
    #[inline]
    pub fn new(v: &'a str) -> Self {
        Self { s: Ok(v) }
    }

    /// DO NOT USE. See <https://github.com/3Hren/msgpack-rust/issues/305>
    #[deprecated(note = "This implementation is unsound and dangerous. See https://github.com/3Hren/msgpack-rust/issues/305")]
    pub fn from_utf8(v: &'a [u8]) -> Self {
        match str::from_utf8(v) {
            Ok(v) => RawRef::new(v),
            Err(err) => {
                Self {
                    s: Err((v, err))
                }
            }
        }
    }

    /// Returns `true` if the raw is valid UTF-8.
    #[inline]
    pub fn is_str(&self) -> bool {
        self.s.is_ok()
    }

    /// Returns `true` if the raw contains invalid UTF-8 sequence.
    #[inline]
    pub fn is_err(&self) -> bool {
        self.s.is_err()
    }

    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
    #[inline]
    pub fn as_str(&self) -> Option<&str> {
        match self.s {
            Ok(ref s) => Some(s),
            Err(..) => None,
        }
    }

    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
    /// else `None`.
    #[inline]
    pub fn as_err(&self) -> Option<&Utf8Error> {
        match self.s {
            Ok(..) => None,
            Err((_, ref err)) => Some(&err),
        }
    }

    /// Returns a byte slice of this raw's contents.
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        match self.s {
            Ok(ref s) => s.as_bytes(),
            Err(ref err) => &err.0[..],
        }
    }
}

impl<'a> Serialize for RawRef<'a> {
    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = match self.s {
            Ok(ref s) => s,
            // FIXME: this is invalid. It should use a newtype hack instead.
            // https://github.com/3Hren/msgpack-rust/issues/305
            Err((ref b, ..)) => unsafe { mem::transmute(b) },
        };

        se.serialize_str(s)
    }
}

struct RawRefVisitor;

impl<'de> de::Visitor<'de> for RawRefVisitor {
    type Value = RawRef<'de>;

    #[cold]
    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        "string or bytes".fmt(fmt)
    }

    #[inline]
    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
        where E: de::Error
    {
        Ok(RawRef { s: Ok(v) })
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
        where E: de::Error
    {
        let s = match str::from_utf8(v) {
            Ok(s) => Ok(s),
            Err(err) => Err((v, err)),
        };

        Ok(RawRef { s })
    }
}

impl<'de> Deserialize<'de> for RawRef<'de> {
    #[inline]
    fn deserialize<D>(de: D) -> Result<Self, D::Error>
        where D: de::Deserializer<'de>
    {
        de.deserialize_any(RawRefVisitor)
    }
}
<|endoftext|>


<commit_before>use std::f32::consts::PI;
use std::sync::{Arc, Mutex,
                mpsc::{Sender, Receiver, TryRecvError},
                atomic::{AtomicUsize, Ordering},
};

use cgmath::{Point3, Vector3, Vector4, prelude::*};

use glium::Rect;

use rand::{self, prelude::*};

use crate::bvh::BVHNode;
use crate::camera::Camera;
use crate::color::Color;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray, RenderCoordinator};
use crate::scene::Scene;
use crate::triangle::{Hit, RTTriangle};

const EPSILON: f32 = 1e-5;
const _EB: f32 = 5.0; // Desired expectation value of bounces
// The matching survival probability from negative binomial distribution
const RR_PROB: f32 = _EB / (_EB + 1.0);

pub struct RenderWorker {
    scene: Arc<Scene>,
    camera: Camera,
    coordinator: Arc<Mutex<RenderCoordinator>>,
    message_rx: Receiver<()>,
    result_tx: Sender<(Rect, Vec<f32>)>,
    ray_count: Arc<AtomicUsize>,
}

impl RenderWorker {
    pub fn new(scene: Arc<Scene>, camera: Camera, coordinator: Arc<Mutex<RenderCoordinator>>,
               message_rx: Receiver<()>, result_tx: Sender<(Rect, Vec<f32>)>,
               ray_count: Arc<AtomicUsize>) -> RenderWorker {
        RenderWorker {
            scene, camera, coordinator,
            message_rx, result_tx,
            ray_count,
        }
    }

    pub fn run(&self) {
        let (width, height) = {
            let coordinator = self.coordinator.lock().unwrap();
            (coordinator.width, coordinator.height)
        };
        let clip_to_world = self.camera.get_world_to_clip().invert().unwrap();
        let mut node_stack: Vec<(&BVHNode, f32)> = Vec::new();
        loop {
            match self.message_rx.try_recv() {
                Err(TryRecvError::Empty) => (),
                Ok(_) => return,
                Err(TryRecvError::Disconnected) => {
                    println!("Threads were not properly stopped before disconnecting channel!");
                    return;
                }
            }
            let block = {
                let mut coordinator = self.coordinator.lock().unwrap();
                coordinator.next_block()
            };
            if let Some(rect) = block {
                let mut block = vec![0.0f32; (3 * rect.width * rect.height) as usize];
                for h in 0..rect.height {
                    for w in 0..rect.width {
                        let samples_per_dir = 2u32;
                        let mut c = Color::black();
                        for j in 0..samples_per_dir {
                            for i in 0..samples_per_dir {
                                let dx = (i as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let dy = (j as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let clip_x = 2.0 * ((rect.left + w) as f32 + dx) / width as f32 - 1.0;
                                let clip_y = 2.0 * ((rect.bottom + h) as f32 + dy) / height as f32 - 1.0;
                                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                                let world_p = clip_to_world * clip_p;
                                let dir = ((world_p / world_p.w).truncate() - self.camera.pos.to_vec())
                                    .normalize();
                                let ray = Ray::new(self.camera.pos, dir, 100.0);
                                c += self.trace_ray(&ray, &mut node_stack, 0);
                            }
                        }
                        c /= samples_per_dir.pow(2) as f32;
                        let pixel_i = 3 * (h * rect.width + w) as usize;
                        block[pixel_i]     = c.r;
                        block[pixel_i + 1] = c.g;
                        block[pixel_i + 2] = c.b;
                    }
                }
                self.result_tx.send((rect, block)).expect("Receiver closed!");
            } else {
                return;
            }
        }
    }

    fn trace_ray(&'a self, ray: &Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>, bounce: u32) -> Color {
        let mut c = Color::black();
        if let Some(hit) = self.find_hit(&ray, node_stack) {
            let material = &self.scene.materials[hit.tri.material_i];
            let mut normal = hit.normal();
            // Flip the normal if its pointing to the opposite side from the hit
            if normal.dot(ray.dir) > 0.0 {
                normal *= -1.0;
            }
            if bounce == 0 {
                if let Some(emissive) = material.emissive {
                    c += normal.dot(-ray.dir).max(0.0) * emissive;
                }
            }
            let (light, light_pos, light_normal, light_pdf) = self.sample_light();
            let bump_pos = hit.pos() + EPSILON * normal;
            let hit_to_light = light_pos - bump_pos;
            let light_dir = hit_to_light.normalize();
            let shadow_ray = Ray::new(bump_pos, light_dir, hit_to_light.magnitude() - EPSILON);
            if shadow_ray.length > 0.1 && self.find_hit(&shadow_ray, node_stack).is_none() {
                let cos_l = light_normal.dot(-light_dir).max(0.0);
                let cos_t = normal.dot(light_dir).max(0.0);
                let light_material = &self.scene.materials[light.material_i];
                let emissive = light_material.emissive.expect("Light wasn't emissive");
                c += emissive * self.brdf(&ray, &shadow_ray, material)
                    * cos_l * cos_t / (hit_to_light.magnitude2() * light_pdf);
            }
            let rr: f32 = rand::random();
            if rr < RR_PROB {
                let (new_dir, mut pdf) = self.sample_dir(normal);
                pdf *= RR_PROB;
                let new_ray = Ray::new(bump_pos, new_dir, 100.0);
                c += normal.dot(new_dir) * self.brdf(&ray, &new_ray, material)
                    * self.trace_ray(&new_ray, node_stack, bounce + 1) / pdf;
            }
        }
        c
    }

    fn brdf(&self, _in_ray: &Ray, _out_ray: &Ray, material: &Material) -> Color {
        material.diffuse / PI
    }

    fn sample_dir(&self, normal: Vector3<f32>) -> (Vector3<f32>, f32) {
        let dir = 2.0 * PI * rand::random::<f32>();
        let length: f32 = rand::random();
        let x = length * dir.cos();
        let y = length * dir.sin();
        let z = (1.0 - length.powi(2)).sqrt();
        let nx = if normal.x.abs() > normal.y.abs() {
            Vector3::new(normal.z, 0.0, -normal.x).normalize()
        } else {
            Vector3::new(0.0, -normal.z, normal.y).normalize()
        };
        let ny = normal.cross(nx);
        (x * nx + y * ny + z * normal, z / PI)
    }

    pub fn sample_light(&self) -> (&RTTriangle, Point3<f32>, Vector3<f32>, f32) {
        if self.scene.lights.is_empty() {
            // TODO: Use camera as a point light
            panic!("Rendered scene has no lights!");
        } else {
            let i = rand::thread_rng().gen_range(0, self.scene.lights.len());
            let light = &self.scene.lights[i];
            let pdf = 1.0 / (self.scene.lights.len() as f32 * light.area());
            let (point, normal) = light.random_point();
            (light, point, normal, pdf)
        }
    }

    fn find_hit(&'a self, ray: &Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>) -> Option<Hit> {
        self.ray_count.fetch_add(1, Ordering::Relaxed);
        let bvh = &self.scene.bvh;
        node_stack.push((bvh.root(), 0.0f32));
        let mut closest_hit: Option<Hit> = None;
        while let Some((node, t)) = node_stack.pop() {
            // We've already found closer hit
            if closest_hit.as_ref().map_or(false, |hit| hit.t <= t) { continue }
            if node.is_leaf() {
                for tri in &self.scene.triangles[node.start_i..node.end_i] {
                    if let Some(hit) = tri.intersect(&ray) {
                        if let Some(closest) = closest_hit.take() {
                            if hit.t < closest.t {
                                closest_hit = Some(hit);
                            } else {
                                closest_hit = Some(closest);
                            }
                        } else {
                            closest_hit = Some(hit);
                        }
                    }
                }
            } else {
                // TODO: put closest hit on top of the stack
                let (left, right) = bvh.get_children(node).expect("Non leaf node had no child nodes!");
                if let Some(t_left) = left.intersect(&ray) {
                    node_stack.push((left, t_left));
                }
                if let Some(t_right) = right.intersect(&ray) {
                    node_stack.push((right, t_right));
                }
            }
        }
        closest_hit
    }
}
<commit_msg>Use camera as the light when there are no other lights<commit_after>use std::f32::consts::PI;
use std::sync::{Arc, Mutex,
                mpsc::{Sender, Receiver, TryRecvError},
                atomic::{AtomicUsize, Ordering},
};

use cgmath::{Point3, Vector3, Vector4, prelude::*};

use glium::Rect;

use rand::{self, prelude::*};

use crate::bvh::BVHNode;
use crate::camera::Camera;
use crate::color::Color;
use crate::material::Material;
use crate::pt_renderer::{Intersect, Ray, RenderCoordinator};
use crate::scene::Scene;
use crate::triangle::Hit;

const EPSILON: f32 = 1e-5;
const _EB: f32 = 5.0; // Desired expectation value of bounces
// The matching survival probability from negative binomial distribution
const RR_PROB: f32 = _EB / (_EB + 1.0);

pub struct RenderWorker {
    scene: Arc<Scene>,
    camera: Camera,
    coordinator: Arc<Mutex<RenderCoordinator>>,
    message_rx: Receiver<()>,
    result_tx: Sender<(Rect, Vec<f32>)>,
    ray_count: Arc<AtomicUsize>,
}

impl RenderWorker {
    pub fn new(scene: Arc<Scene>, camera: Camera, coordinator: Arc<Mutex<RenderCoordinator>>,
               message_rx: Receiver<()>, result_tx: Sender<(Rect, Vec<f32>)>,
               ray_count: Arc<AtomicUsize>) -> RenderWorker {
        RenderWorker {
            scene, camera, coordinator,
            message_rx, result_tx,
            ray_count,
        }
    }

    pub fn run(&self) {
        let (width, height) = {
            let coordinator = self.coordinator.lock().unwrap();
            (coordinator.width, coordinator.height)
        };
        let clip_to_world = self.camera.get_world_to_clip().invert().unwrap();
        let mut node_stack: Vec<(&BVHNode, f32)> = Vec::new();
        loop {
            match self.message_rx.try_recv() {
                Err(TryRecvError::Empty) => (),
                Ok(_) => return,
                Err(TryRecvError::Disconnected) => {
                    println!("Threads were not properly stopped before disconnecting channel!");
                    return;
                }
            }
            let block = {
                let mut coordinator = self.coordinator.lock().unwrap();
                coordinator.next_block()
            };
            if let Some(rect) = block {
                let mut block = vec![0.0f32; (3 * rect.width * rect.height) as usize];
                for h in 0..rect.height {
                    for w in 0..rect.width {
                        let samples_per_dir = 2u32;
                        let mut c = Color::black();
                        for j in 0..samples_per_dir {
                            for i in 0..samples_per_dir {
                                let dx = (i as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let dy = (j as f32 + rand::random::<f32>()) / samples_per_dir as f32;
                                let clip_x = 2.0 * ((rect.left + w) as f32 + dx) / width as f32 - 1.0;
                                let clip_y = 2.0 * ((rect.bottom + h) as f32 + dy) / height as f32 - 1.0;
                                let clip_p = Vector4::new(clip_x, clip_y, 1.0, 1.0);
                                let world_p = clip_to_world * clip_p;
                                let dir = ((world_p / world_p.w).truncate() - self.camera.pos.to_vec())
                                    .normalize();
                                let ray = Ray::new(self.camera.pos, dir, 100.0);
                                c += self.trace_ray(&ray, &mut node_stack, 0);
                            }
                        }
                        c /= samples_per_dir.pow(2) as f32;
                        let pixel_i = 3 * (h * rect.width + w) as usize;
                        block[pixel_i]     = c.r;
                        block[pixel_i + 1] = c.g;
                        block[pixel_i + 2] = c.b;
                    }
                }
                self.result_tx.send((rect, block)).expect("Receiver closed!");
            } else {
                return;
            }
        }
    }

    fn trace_ray(&'a self, ray: &Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>, bounce: u32) -> Color {
        let mut c = Color::black();
        if let Some(hit) = self.find_hit(&ray, node_stack) {
            let material = &self.scene.materials[hit.tri.material_i];
            let mut normal = hit.normal();
            // Flip the normal if its pointing to the opposite side from the hit
            if normal.dot(ray.dir) > 0.0 {
                normal *= -1.0;
            }
            if bounce == 0 {
                if let Some(emissive) = material.emissive {
                    c += normal.dot(-ray.dir).max(0.0) * emissive;
                }
            }
            let (emissive, light_pos, light_normal, light_pdf) = self.sample_light();
            let bump_pos = hit.pos() + EPSILON * normal;
            let hit_to_light = light_pos - bump_pos;
            let light_dir = hit_to_light.normalize();
            let shadow_ray = Ray::new(bump_pos, light_dir, hit_to_light.magnitude() - EPSILON);
            if shadow_ray.length > 0.1 && self.find_hit(&shadow_ray, node_stack).is_none() {
                let cos_l = light_normal.dot(-light_dir).max(0.0);
                let cos_t = normal.dot(light_dir).max(0.0);
                c += emissive * self.brdf(&ray, &shadow_ray, material)
                    * cos_l * cos_t / (hit_to_light.magnitude2() * light_pdf);
            }
            let rr: f32 = rand::random();
            if rr < RR_PROB {
                let (new_dir, mut pdf) = self.sample_dir(normal);
                pdf *= RR_PROB;
                let new_ray = Ray::new(bump_pos, new_dir, 100.0);
                c += normal.dot(new_dir) * self.brdf(&ray, &new_ray, material)
                    * self.trace_ray(&new_ray, node_stack, bounce + 1) / pdf;
            }
        }
        c
    }

    fn brdf(&self, _in_ray: &Ray, _out_ray: &Ray, material: &Material) -> Color {
        material.diffuse / PI
    }

    fn sample_dir(&self, normal: Vector3<f32>) -> (Vector3<f32>, f32) {
        let dir = 2.0 * PI * rand::random::<f32>();
        let length: f32 = rand::random();
        let x = length * dir.cos();
        let y = length * dir.sin();
        let z = (1.0 - length.powi(2)).sqrt();
        let nx = if normal.x.abs() > normal.y.abs() {
            Vector3::new(normal.z, 0.0, -normal.x).normalize()
        } else {
            Vector3::new(0.0, -normal.z, normal.y).normalize()
        };
        let ny = normal.cross(nx);
        (x * nx + y * ny + z * normal, z / PI)
    }

    pub fn sample_light(&self) -> (Color, Point3<f32>, Vector3<f32>, f32) {
        if self.scene.lights.is_empty() {
            (10.0 * Color::white(), self.camera.pos, self.camera.dir, 1.0)
        } else {
            let i = rand::thread_rng().gen_range(0, self.scene.lights.len());
            let light = &self.scene.lights[i];
            let pdf = 1.0 / (self.scene.lights.len() as f32 * light.area());
            let (point, normal) = light.random_point();
            let light_material = &self.scene.materials[light.material_i];
            let emissive = light_material.emissive.expect("Light wasn't emissive");
            (emissive, point, normal, pdf)
        }
    }

    fn find_hit(&'a self, ray: &Ray, node_stack: &mut Vec<(&'a BVHNode, f32)>) -> Option<Hit> {
        self.ray_count.fetch_add(1, Ordering::Relaxed);
        let bvh = &self.scene.bvh;
        node_stack.push((bvh.root(), 0.0f32));
        let mut closest_hit: Option<Hit> = None;
        while let Some((node, t)) = node_stack.pop() {
            // We've already found closer hit
            if closest_hit.as_ref().map_or(false, |hit| hit.t <= t) { continue }
            if node.is_leaf() {
                for tri in &self.scene.triangles[node.start_i..node.end_i] {
                    if let Some(hit) = tri.intersect(&ray) {
                        if let Some(closest) = closest_hit.take() {
                            if hit.t < closest.t {
                                closest_hit = Some(hit);
                            } else {
                                closest_hit = Some(closest);
                            }
                        } else {
                            closest_hit = Some(hit);
                        }
                    }
                }
            } else {
                // TODO: put closest hit on top of the stack
                let (left, right) = bvh.get_children(node).expect("Non leaf node had no child nodes!");
                if let Some(t_left) = left.intersect(&ray) {
                    node_stack.push((left, t_left));
                }
                if let Some(t_right) = right.intersect(&ray) {
                    node_stack.push((right, t_right));
                }
            }
        }
        closest_hit
    }
}
<|endoftext|>


<commit_before>use super::{git2, Error, Reference, Statuses};
use std::path::{Path, PathBuf};

pub struct GitRepo {
    path: PathBuf,
    repo: git2::Repository,
}

unsafe impl Send for GitRepo {}

impl GitRepo {
    pub fn open<P>(path: P) -> Result<Self, Error>
    where
        P: Into<PathBuf>,
        P: AsRef<Path>,
    {
        let owned_path = path.into();
        let git_repo = git2::Repository::open(&owned_path)?;

        let repo = Self {
            path: owned_path,
            repo: git_repo,
        };

        Ok(repo)
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn statuses(&self) -> Result<Statuses, Error> {
        let mut opts = git2::StatusOptions::new();

        opts.include_ignored(false)
            .include_untracked(true)
            .recurse_untracked_dirs(true)
            .include_unreadable_as_untracked(true)
            .disable_pathspec_match(true)
            .exclude_submodules(true);

        self.repo
            .statuses(Some(&mut opts))
            .map(|x| x.into())
            .map_err(|x| x.into())
    }

    pub fn reset(&self) -> Result<Reference, Error> {
        let head = self.repo.head()?;
        let obj = head.peel(git2::ObjectType::Any)?;

        self.repo.reset(&obj, git2::ResetType::Hard, None)?;

        Reference::new(&head)
    }

    pub fn checkout(&self, branch_name: &str) -> Result<bool, Error> {
        let components = branch_name.split('/').collect::<Vec<_>>();

        let branch_type = match components.len() {
            0 => return Err(Error::ZeroSizedBranchName),
            1 => git2::BranchType::Local,
            _ => {
                if self.repo.find_remote(&components[0]).is_ok() {
                    git2::BranchType::Remote
                } else {
                    git2::BranchType::Local
                }
            }
        };

        let branch = self.repo.find_branch(branch_name, branch_type)?;

        let obj = branch.get().peel(git2::ObjectType::Commit)?;

        match branch_type {
            git2::BranchType::Local => self.checkout_local(branch_name, &obj),
            git2::BranchType::Remote => self.checkout_remote(&obj),
        }
    }

    fn checkout_local(&self, branch_name: &str, obj: &git2::Object) -> Result<bool, Error> {
        let mut opts = git2::build::CheckoutBuilder::new();

        self.repo.checkout_tree(obj, Some(&mut opts))?;

        let branch_str = format!("refs/heads/{}", branch_name);
        let branch_ref = self.repo.find_reference(&branch_str)?;

        self.repo
            .set_head(branch_ref.name().unwrap())
            .expect("Error setting head");

        Ok(true)
    }

    fn checkout_remote(&self, obj: &git2::Object) -> Result<bool, Error> {
        let head_id = self.repo
            .head()
            .expect("Could not resolve head")
            .peel(git2::ObjectType::Any)
            .expect("Could not get head ref")
            .id();

        if head_id == obj.id() {
            return Ok(false);
        }

        self.repo.set_head_detached(obj.id()).expect("wut");
        self.repo
            .reset(obj, git2::ResetType::Hard, None)
            .expect("wuufttttt");

        Ok(true)
    }

    pub fn delete_local_branch(&self, branch_name: &str) -> Result<(), Error> {
        self.repo
            .find_branch(branch_name, git2::BranchType::Local)?
            .delete()?;

        Ok(())
    }

    pub fn has_local_branch(&self, branch_name: &str) -> Result<(), Error> {
        self.repo.find_branch(branch_name, git2::BranchType::Local)?;

        Ok(())
    }
}
<commit_msg>Restructured repo a bit<commit_after>use super::{git2, Error, Reference, Statuses};
use std::path::{Path, PathBuf};

pub struct GitRepo {
    path: PathBuf,
    repo: git2::Repository,
}

unsafe impl Send for GitRepo {}

impl GitRepo {
    pub fn open<P>(path: P) -> Result<Self, Error>
    where
        P: Into<PathBuf>,
        P: AsRef<Path>,
    {
        let owned_path = path.into();
        let git_repo = git2::Repository::open(&owned_path)?;

        let repo = Self {
            path: owned_path,
            repo: git_repo,
        };

        Ok(repo)
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn statuses(&self) -> Result<Statuses, Error> {
        let mut opts = git2::StatusOptions::new();

        opts.include_ignored(false)
            .include_untracked(true)
            .recurse_untracked_dirs(true)
            .include_unreadable_as_untracked(true)
            .disable_pathspec_match(true)
            .exclude_submodules(true);

        self.repo
            .statuses(Some(&mut opts))
            .map(|x| x.into())
            .map_err(|x| x.into())
    }

    pub fn reset(&self) -> Result<Reference, Error> {
        let head = self.repo.head()?;
        let obj = head.peel(git2::ObjectType::Any)?;

        self.repo.reset(&obj, git2::ResetType::Hard, None)?;

        Reference::new(&head)
    }

    pub fn checkout(&self, branch_name: &str) -> Result<bool, Error> {
        let branch_type = self.get_branch_type(branch_name)?;
        let branch = self.repo.find_branch(branch_name, branch_type)?;
        let obj = branch.get().peel(git2::ObjectType::Commit)?;

        match branch_type {
            git2::BranchType::Local => self.checkout_local(branch_name, &obj),
            git2::BranchType::Remote => self.checkout_remote(&obj),
        }
    }

    pub fn delete_local_branch(&self, branch_name: &str) -> Result<(), Error> {
        self.repo
            .find_branch(branch_name, git2::BranchType::Local)?
            .delete()?;

        Ok(())
    }

    pub fn has_local_branch(&self, branch_name: &str) -> Result<(), Error> {
        self.repo.find_branch(branch_name, git2::BranchType::Local)?;

        Ok(())
    }

    fn get_branch_type(&self, branch_name: &str) -> Result<git2::BranchType, Error> {
        let components = branch_name.split('/').collect::<Vec<_>>();

        match components.len() {
            0 => Err(Error::ZeroSizedBranchName),
            1 => Ok(git2::BranchType::Local),
            _ => {
                if self.repo.find_remote(&components[0]).is_ok() {
                    Ok(git2::BranchType::Remote)
                } else {
                    Ok(git2::BranchType::Local)
                }
            }
        }
    }

    fn checkout_local(&self, branch_name: &str, obj: &git2::Object) -> Result<bool, Error> {
        self.repo.checkout_tree(obj, None)?;

        let branch_str = format!("refs/heads/{}", branch_name);
        let branch_ref = self.repo.find_reference(&branch_str)?;

        self.repo
            .set_head(branch_ref.name().expect("Error setting head"))
            .expect("Error setting head");

        Ok(true)
    }

    fn checkout_remote(&self, obj: &git2::Object) -> Result<bool, Error> {
        let head_id = self.repo
            .head()
            .expect("Could not resolve head")
            .peel(git2::ObjectType::Any)
            .expect("Could not get head ref")
            .id();

        if head_id == obj.id() {
            return Ok(false);
        }

        self.repo
            .set_head_detached(obj.id())
            .expect("Error setting head detatched");
        self.repo
            .reset(obj, git2::ResetType::Hard, None)
            .expect("Reset error");

        Ok(true)
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::string::String;
use std::io::Write; // Used for flush implicitly?

fn main() {
    let name  = get_name();
    println!("Hello {}", name);
}

fn get_name() -> String {
    print!("Enter name: ");
    io::stdout().flush();
    let stdin = io::stdin();
    let mut name = String::new();
    stdin.read_line(&mut name);
    return name;
}
<commit_msg>Added topping<commit_after>use std::io;
use std::string::String;
use std::io::Write; // Used for flush implicitly?
use std::str;

struct Topping<'a> {
    name: &'a str,
    price: f32
}

fn main() {
    let stdin = io::stdin();
    let name  = get_name(stdin);
    println!("Hello {}", name);
    str_topping(get_topping());
}

fn get_topping<'a>() -> Topping<'a> {
    return Topping {name: "Salami", price: 0.7}
}

fn str_topping(topping: Topping) {
    println!("{} - {}", topping.name, topping.price)
}

fn get_name(stdin: io::Stdin) -> String {
    print!("Enter name: ");
    io::stdout().flush();
    let mut name = String::new();
    stdin.read_line(&mut name);
    return name;
}
<|endoftext|>


<commit_before>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::firmware::{
    self,
    installation_set::{self, Set},
};
use chrono::{DateTime, NaiveDateTime, Utc};
use derive_more::{Deref, DerefMut, Display, Error, From};
use sdk::api::info::runtime_settings as api;
use slog_scope::{debug, warn};
use std::{fs, io, path::Path};

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, Display, Error, From)]
pub enum Error {
    Io(io::Error),
    SerdeJson(serde_json::Error),
    FirmwareError(firmware::Error),

    #[display("invalid runtime settings destination")]
    InvalidDestination,
}

#[derive(Clone, Debug, Deref, DerefMut, PartialEq)]
pub struct RuntimeSettings(pub api::RuntimeSettings);

impl Default for RuntimeSettings {
    fn default() -> Self {
        RuntimeSettings(api::RuntimeSettings {
            polling: api::RuntimePolling {
                last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
                retries: 0,
                now: false,
                server_address: api::ServerAddress::Default,
            },
            update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
            path: std::path::PathBuf::new(),
            persistent: false,
        })
    }
}

impl RuntimeSettings {
    pub fn load(path: &Path) -> Result<Self> {
        let mut this = if path.exists() {
            debug!("loading runtime settings from {:?}", path);
            match fs::read_to_string(path).map_err(Error::from).and_then(|ref s| Self::parse(s)) {
                Ok(v) => v,
                Err(e) => {
                    warn!("failed to load current runtime settings: {}", e);
                    let _ = fs::rename(
                        path,
                        path.with_file_name(format!(
                            "{}.old",
                            path.file_name().unwrap().to_str().unwrap()
                        )),
                    );
                    debug!("using default runtime settings");
                    Self::default()
                }
            }
        } else {
            debug!("runtime settings file {:?} does not exists, using default settings", path);
            Self::default()
        };

        this.path = path.to_path_buf();
        Ok(this)
    }

    fn parse(content: &str) -> Result<Self> {
        Ok(RuntimeSettings(serde_json::from_str::<api::RuntimeSettings>(&content)?))
    }

    fn save(&self) -> Result<()> {
        if !self.persistent {
            debug!("skipping runtime settings save, using non-persistent");
            return Ok(());
        }

        let parent = self.path.parent().ok_or(Error::InvalidDestination)?;
        if !parent.exists() {
            debug!("creating runtime settings to store state");
            fs::create_dir_all(parent)?;
        }

        fs::write(&self.path, self.serialize()?)?;
        debug!("saved runtime settings to {:?}", &self.path);

        Ok(())
    }

    fn serialize(&self) -> Result<String> {
        Ok(serde_json::to_string(&self.0)?)
    }

    pub(crate) fn get_inactive_installation_set(&self) -> Result<Set> {
        Ok(match self.update.upgrade_to_installation {
            // If upgrade_to_installation has already been set
            // the current inactive installation_set will already be swapped
            // so we can just install over the same one as before
            Some(s) => Set(s),
            // If no installation has been made so far we can check
            // the system for the current inactive installation set
            None => installation_set::inactive()?,
        })
    }

    pub(crate) fn enable_persistency(&mut self) {
        self.persistent = true;
    }

    pub(crate) fn is_polling_forced(&self) -> bool {
        self.polling.now
    }

    pub(crate) fn disable_force_poll(&mut self) -> Result<()> {
        debug!("disabling foce poll");
        self.polling.now = false;
        self.save()
    }

    pub(crate) fn retries(&self) -> usize {
        self.polling.retries
    }

    pub(crate) fn inc_retries(&mut self) {
        self.polling.retries += 1;
    }

    pub(crate) fn clear_retries(&mut self) {
        self.polling.retries = 0;
    }

    pub(crate) fn last_polling(&self) -> DateTime<Utc> {
        self.polling.last
    }

    pub(crate) fn set_last_polling(&mut self, last_polling: DateTime<Utc>) -> Result<()> {
        debug!("updating last polling time");
        self.polling.last = last_polling;
        self.save()
    }

    pub(crate) fn applied_package_uid(&self) -> Option<String> {
        self.update.applied_package_uid.clone()
    }

    pub(crate) fn set_applied_package_uid(&mut self, applied_package_uid: &str) -> Result<()> {
        debug!("marking package {} as installed", applied_package_uid);
        self.update.applied_package_uid = Some(applied_package_uid.to_string());
        self.save()
    }

    pub(crate) fn set_upgrading_to(&mut self, new_install_set: Set) -> Result<()> {
        debug!("setting upgrading to {}", new_install_set);
        self.update.upgrade_to_installation = Some(new_install_set.0);
        self.save()
    }

    pub(crate) fn custom_server_address(&self) -> Option<&str> {
        match &self.polling.server_address {
            api::ServerAddress::Custom(s) => Some(s),
            api::ServerAddress::Default => None,
        }
    }

    pub(crate) fn set_custom_server_address(&mut self, server_address: &str) {
        self.polling.server_address = api::ServerAddress::Custom(server_address.to_owned());
    }

    /// Reset settings that are only need through a single installation
    pub(crate) fn reset_transient_settings(&mut self) {
        // Server address is reset so it doesn't keep probing the last custom server
        // requested
        self.polling.server_address = api::ServerAddress::Default;
    }

    pub(crate) fn reset_installation_settings(&mut self) -> Result<()> {
        debug!("reseting installation settings");
        self.update.upgrade_to_installation = None;
        self.update.applied_package_uid = None;

        // Ensure we do a probe as soon as possible so full update
        // cycle can be finished.
        self.polling.now = true;

        self.save()
    }
}

#[test]
fn default() {
    use pretty_assertions::assert_eq;
    let settings = RuntimeSettings::default();
    let expected = RuntimeSettings(api::RuntimeSettings {
        polling: api::RuntimePolling {
            last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
            retries: 0,
            now: false,
            server_address: api::ServerAddress::Default,
        },
        update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
        path: std::path::PathBuf::new(),
        persistent: false,
    });

    assert_eq!(Some(settings), Some(expected));
}

#[test]
fn load_and_save() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::remove_file(&settings_file).unwrap();

    let mut settings = RuntimeSettings::load(settings_file).unwrap();
    settings.reset_installation_settings().unwrap();

    let new_settings = RuntimeSettings::load(settings_file).unwrap();

    assert_eq!(settings.update, new_settings.update);
}

#[test]
fn load_bad_formated_file() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::write(&settings_file, "foo").unwrap();

    let load_result = RuntimeSettings::load(settings_file);
    assert!(load_result.is_ok(), "We should fail when reading a unformated formatted file");

    let old_file = settings_file
        .with_file_name(format!("{}.old", settings_file.file_name().unwrap().to_str().unwrap()));
    let old_content = fs::read_to_string(&old_file).unwrap();
    assert_eq!(
        old_content, "foo",
        "Old file should still be accessible as a .old file in the same directory"
    );
    fs::remove_file(old_file).unwrap();
}
<commit_msg>updatehub: runtime_settings: Simplify `get_inactive_installation_set`<commit_after>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::firmware::{
    self,
    installation_set::{self, Set},
};
use chrono::{DateTime, NaiveDateTime, Utc};
use derive_more::{Deref, DerefMut, Display, Error, From};
use sdk::api::info::runtime_settings as api;
use slog_scope::{debug, warn};
use std::{fs, io, path::Path};

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, Display, Error, From)]
pub enum Error {
    Io(io::Error),
    SerdeJson(serde_json::Error),
    FirmwareError(firmware::Error),

    #[display("invalid runtime settings destination")]
    InvalidDestination,
}

#[derive(Clone, Debug, Deref, DerefMut, PartialEq)]
pub struct RuntimeSettings(pub api::RuntimeSettings);

impl Default for RuntimeSettings {
    fn default() -> Self {
        RuntimeSettings(api::RuntimeSettings {
            polling: api::RuntimePolling {
                last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
                retries: 0,
                now: false,
                server_address: api::ServerAddress::Default,
            },
            update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
            path: std::path::PathBuf::new(),
            persistent: false,
        })
    }
}

impl RuntimeSettings {
    pub fn load(path: &Path) -> Result<Self> {
        let mut this = if path.exists() {
            debug!("loading runtime settings from {:?}", path);
            match fs::read_to_string(path).map_err(Error::from).and_then(|ref s| Self::parse(s)) {
                Ok(v) => v,
                Err(e) => {
                    warn!("failed to load current runtime settings: {}", e);
                    let _ = fs::rename(
                        path,
                        path.with_file_name(format!(
                            "{}.old",
                            path.file_name().unwrap().to_str().unwrap()
                        )),
                    );
                    debug!("using default runtime settings");
                    Self::default()
                }
            }
        } else {
            debug!("runtime settings file {:?} does not exists, using default settings", path);
            Self::default()
        };

        this.path = path.to_path_buf();
        Ok(this)
    }

    fn parse(content: &str) -> Result<Self> {
        Ok(RuntimeSettings(serde_json::from_str::<api::RuntimeSettings>(&content)?))
    }

    fn save(&self) -> Result<()> {
        if !self.persistent {
            debug!("skipping runtime settings save, using non-persistent");
            return Ok(());
        }

        let parent = self.path.parent().ok_or(Error::InvalidDestination)?;
        if !parent.exists() {
            debug!("creating runtime settings to store state");
            fs::create_dir_all(parent)?;
        }

        fs::write(&self.path, self.serialize()?)?;
        debug!("saved runtime settings to {:?}", &self.path);

        Ok(())
    }

    fn serialize(&self) -> Result<String> {
        Ok(serde_json::to_string(&self.0)?)
    }

    pub(crate) fn get_inactive_installation_set(&self) -> Result<Set> {
        // If the `upgrade_to_installation` is defined, the current inactive
        // installation_set has already been swapped.
        if let Some(s) = self.update.upgrade_to_installation {
            return Ok(Set(s));
        }

        Ok(installation_set::inactive()?)
    }

    pub(crate) fn enable_persistency(&mut self) {
        self.persistent = true;
    }

    pub(crate) fn is_polling_forced(&self) -> bool {
        self.polling.now
    }

    pub(crate) fn disable_force_poll(&mut self) -> Result<()> {
        debug!("disabling foce poll");
        self.polling.now = false;
        self.save()
    }

    pub(crate) fn retries(&self) -> usize {
        self.polling.retries
    }

    pub(crate) fn inc_retries(&mut self) {
        self.polling.retries += 1;
    }

    pub(crate) fn clear_retries(&mut self) {
        self.polling.retries = 0;
    }

    pub(crate) fn last_polling(&self) -> DateTime<Utc> {
        self.polling.last
    }

    pub(crate) fn set_last_polling(&mut self, last_polling: DateTime<Utc>) -> Result<()> {
        debug!("updating last polling time");
        self.polling.last = last_polling;
        self.save()
    }

    pub(crate) fn applied_package_uid(&self) -> Option<String> {
        self.update.applied_package_uid.clone()
    }

    pub(crate) fn set_applied_package_uid(&mut self, applied_package_uid: &str) -> Result<()> {
        debug!("marking package {} as installed", applied_package_uid);
        self.update.applied_package_uid = Some(applied_package_uid.to_string());
        self.save()
    }

    pub(crate) fn set_upgrading_to(&mut self, new_install_set: Set) -> Result<()> {
        debug!("setting upgrading to {}", new_install_set);
        self.update.upgrade_to_installation = Some(new_install_set.0);
        self.save()
    }

    pub(crate) fn custom_server_address(&self) -> Option<&str> {
        match &self.polling.server_address {
            api::ServerAddress::Custom(s) => Some(s),
            api::ServerAddress::Default => None,
        }
    }

    pub(crate) fn set_custom_server_address(&mut self, server_address: &str) {
        self.polling.server_address = api::ServerAddress::Custom(server_address.to_owned());
    }

    /// Reset settings that are only need through a single installation
    pub(crate) fn reset_transient_settings(&mut self) {
        // Server address is reset so it doesn't keep probing the last custom server
        // requested
        self.polling.server_address = api::ServerAddress::Default;
    }

    pub(crate) fn reset_installation_settings(&mut self) -> Result<()> {
        debug!("reseting installation settings");
        self.update.upgrade_to_installation = None;
        self.update.applied_package_uid = None;

        // Ensure we do a probe as soon as possible so full update
        // cycle can be finished.
        self.polling.now = true;

        self.save()
    }
}

#[test]
fn default() {
    use pretty_assertions::assert_eq;
    let settings = RuntimeSettings::default();
    let expected = RuntimeSettings(api::RuntimeSettings {
        polling: api::RuntimePolling {
            last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
            retries: 0,
            now: false,
            server_address: api::ServerAddress::Default,
        },
        update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
        path: std::path::PathBuf::new(),
        persistent: false,
    });

    assert_eq!(Some(settings), Some(expected));
}

#[test]
fn load_and_save() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::remove_file(&settings_file).unwrap();

    let mut settings = RuntimeSettings::load(settings_file).unwrap();
    settings.reset_installation_settings().unwrap();

    let new_settings = RuntimeSettings::load(settings_file).unwrap();

    assert_eq!(settings.update, new_settings.update);
}

#[test]
fn load_bad_formated_file() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::write(&settings_file, "foo").unwrap();

    let load_result = RuntimeSettings::load(settings_file);
    assert!(load_result.is_ok(), "We should fail when reading a unformated formatted file");

    let old_file = settings_file
        .with_file_name(format!("{}.old", settings_file.file_name().unwrap().to_str().unwrap()));
    let old_content = fs::read_to_string(&old_file).unwrap();
    assert_eq!(
        old_content, "foo",
        "Old file should still be accessible as a .old file in the same directory"
    );
    fs::remove_file(old_file).unwrap();
}
<|endoftext|>


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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}
use foo::MyTrait::do_something;
```

It's illegal to directly import methods belonging to a trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0403: r##"
Some type parameters have the same name. Example of erroneous code:

```
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
                            //        parameter in this type parameter list
```

Please verify that none of the type parameterss are misspelled, and rename any
clashing parameters. Example:

```
fn foo<T, Y>(s: T, u: Y) {} // ok!
```
"##,

E0404: r##"
You tried to implement something which was not a trait on an object. Example of
erroneous code:

```
struct Foo;
struct Bar;

impl Foo for Bar {} // error: `Foo` is not a trait
```

Please verify that you didn't misspell the trait's name or otherwise use the
wrong identifier. Example:

```
trait Foo {
    // some functions
}
struct Bar;

impl Foo for Bar { // ok!
    // functions implementation
}
```
"##,

E0405: r##"
An unknown trait was implemented. Example of erroneous code:

```
struct Foo;

impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
```

Please verify that the name of the trait wasn't misspelled and ensure that it
was imported. Example:

```
// solution 1:
use some_file::SomeTrait;

// solution 2:
trait SomeTrait {
    // some functions
}

struct Foo;

impl SomeTrait for Foo { // ok!
    // implements functions
}
```
"##,

E0407: r##"
A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // error: method `b` is not a member of trait `Foo`
}
```

Please verify you didn't misspell the method name and you used the correct
trait. First example:

```
trait Foo {
    fn a();
    fn b();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // ok!
}
```

Second example:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
}

impl Bar {
    fn b() {}
}
```
"##,

E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code:

```
static FOO : i32 = 0;

match 0 {
    FOO => {} // error: static variables cannot be referenced in a
              //        pattern, use a `const` instead
    _ => {}
}
```

The compiler needs to know the value of the pattern at compile time;
compile-time patterns can defined via const or enum items. Please verify
that the identifier is spelled correctly, and if so, use a const instead
of static to define it. Example:

```
const FOO : i32 = 0;

match 0 {
    FOO => {} // ok!
    _ => {}
}
```
"##,

E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo() {
        self.bar(); // error: `self` is not available in a static method.
    }
}
```

Please check if the method's argument list should have contained self,
&self, or &mut self (in case you didn't want to create a static method),
and add it if so. Example:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo(self) {
        self.bar(); // ok!
    }
}
```
"##,

E0428: r##"
A type or module has been defined more than once. Example of erroneous
code:

```
struct Bar;
struct Bar; // error: duplicate definition of value `Bar`
```

Please verify you didn't misspell the type/module's name or remove/rename the
duplicated one. Example:

```
struct Bar;
struct Bar2; // ok!
```
"##,

E0433: r##"
Invalid import. Example of erroneous code:

```
use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist`
```

Please verify you didn't misspell the import's name.
"##,

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0406, // undeclared associated type
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0434, // can't capture dynamic environment in a fn item
    E0435, // attempt to use a non-constant value in a constant
    E0437, // type is not a member of trait
    E0438, // const is not a member of trait
}
<commit_msg>Add E0430 error explanation<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}
use foo::MyTrait::do_something;
```

It's illegal to directly import methods belonging to a trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0403: r##"
Some type parameters have the same name. Example of erroneous code:

```
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
                            //        parameter in this type parameter list
```

Please verify that none of the type parameterss are misspelled, and rename any
clashing parameters. Example:

```
fn foo<T, Y>(s: T, u: Y) {} // ok!
```
"##,

E0404: r##"
You tried to implement something which was not a trait on an object. Example of
erroneous code:

```
struct Foo;
struct Bar;

impl Foo for Bar {} // error: `Foo` is not a trait
```

Please verify that you didn't misspell the trait's name or otherwise use the
wrong identifier. Example:

```
trait Foo {
    // some functions
}
struct Bar;

impl Foo for Bar { // ok!
    // functions implementation
}
```
"##,

E0405: r##"
An unknown trait was implemented. Example of erroneous code:

```
struct Foo;

impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
```

Please verify that the name of the trait wasn't misspelled and ensure that it
was imported. Example:

```
// solution 1:
use some_file::SomeTrait;

// solution 2:
trait SomeTrait {
    // some functions
}

struct Foo;

impl SomeTrait for Foo { // ok!
    // implements functions
}
```
"##,

E0407: r##"
A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // error: method `b` is not a member of trait `Foo`
}
```

Please verify you didn't misspell the method name and you used the correct
trait. First example:

```
trait Foo {
    fn a();
    fn b();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // ok!
}
```

Second example:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
}

impl Bar {
    fn b() {}
}
```
"##,

E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code:

```
static FOO : i32 = 0;

match 0 {
    FOO => {} // error: static variables cannot be referenced in a
              //        pattern, use a `const` instead
    _ => {}
}
```

The compiler needs to know the value of the pattern at compile time;
compile-time patterns can defined via const or enum items. Please verify
that the identifier is spelled correctly, and if so, use a const instead
of static to define it. Example:

```
const FOO : i32 = 0;

match 0 {
    FOO => {} // ok!
    _ => {}
}
```
"##,

E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo() {
        self.bar(); // error: `self` is not available in a static method.
    }
}
```

Please check if the method's argument list should have contained self,
&self, or &mut self (in case you didn't want to create a static method),
and add it if so. Example:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo(self) {
        self.bar(); // ok!
    }
}
```
"##,

E0428: r##"
A type or module has been defined more than once. Example of erroneous
code:

```
struct Bar;
struct Bar; // error: duplicate definition of value `Bar`
```

Please verify you didn't misspell the type/module's name or remove/rename the
duplicated one. Example:

```
struct Bar;
struct Bar2; // ok!
```
"##,

E0430: r##"
The `self` import appears more than once in the list.

```
use something::{self, self}; // error: `self` import can only appear once in
                             //        the list
```

Please verify you didn't misspell the import name or remove the duplicated
`self` import.
"##,

E0433: r##"
Invalid import. Example of erroneous code:

```
use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist`
```

Please verify you didn't misspell the import's name.
"##,

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0406, // undeclared associated type
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0429, // `self` imports are only allowed within a { } list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0434, // can't capture dynamic environment in a fn item
    E0435, // attempt to use a non-constant value in a constant
    E0437, // type is not a member of trait
    E0438, // const is not a member of trait
}
<|endoftext|>


<commit_before>use std::ops;
use std::cmp::Ordering;

use index::Index;

#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub enum Value {
    Bool(bool),
    String(String),
    Float(f64),
    Tuple(Tuple),
    Relation(Relation),
}
pub type Tuple = Vec<Value>;
pub type Relation = Index<Vec<Value>>; // a set of tuples
pub type Id = String; // TODO use uuid?

impl Ord for Value {
    fn cmp(&self, other: &Value) -> Ordering {
        self.partial_cmp(other).unwrap() // TODO this will panic on NaN
    }
}

impl Eq for Value {} // TODO this is unsafe for NaN

impl ops::Index<usize> for Value {
    type Output = Value;

    fn index(&self, index: usize) -> &Value {
        match *self {
            Value::Tuple(ref tuple) => tuple.index(index),
            _ => panic!("Cannot index into this non-tuple value: {:?}", self),
        }
    }
}

impl Value {
    pub fn as_str(&self) -> &str {
        match *self {
            Value::String(ref string) => &*string,
            _ => panic!("Cannot convert this to string: {:?}", self),
        }
    }

    pub fn as_slice(&self) -> &[Value] {
        match *self {
            Value::Tuple(ref tuple) => &*tuple,
            _ => panic!("Cannot convert this to tuple: {:?}", self),
        }
    }
    pub fn to_f64(&self) -> Option<f64> {
        match *self {
            Value::Float(float) => Some(float as f64),
            _ => None,
        }
    }
    pub fn to_i64(&self) -> Option<i64> {
        match *self {
            Value::Float(float) => {
                let result = float as i64;
                if (float == (result as f64)) {
                    Some(result)
                } else {
                    None
                }
            }
            _ => None,
        }
    }
    pub fn to_usize(&self) -> Option<usize> {
        match *self {
            Value::Float(float) => {
                let result = float as usize;
                if (float == (result as f64)) {
                    Some(result)
                } else {
                    None
                }
            },
            _ => None,
        }
    }
}<commit_msg>Fix warnings<commit_after>use std::ops;
use std::cmp::Ordering;

use index::Index;

#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub enum Value {
    Bool(bool),
    String(String),
    Float(f64),
    Tuple(Tuple),
    Relation(Relation),
}
pub type Tuple = Vec<Value>;
pub type Relation = Index<Vec<Value>>; // a set of tuples
pub type Id = String; // TODO use uuid?

impl Ord for Value {
    fn cmp(&self, other: &Value) -> Ordering {
        self.partial_cmp(other).unwrap() // TODO this will panic on NaN
    }
}

impl Eq for Value {} // TODO this is unsafe for NaN

impl ops::Index<usize> for Value {
    type Output = Value;

    fn index(&self, index: usize) -> &Value {
        match *self {
            Value::Tuple(ref tuple) => tuple.index(index),
            _ => panic!("Cannot index into this non-tuple value: {:?}", self),
        }
    }
}

impl Value {
    pub fn as_str(&self) -> &str {
        match *self {
            Value::String(ref string) => &*string,
            _ => panic!("Cannot convert this to string: {:?}", self),
        }
    }

    pub fn as_slice(&self) -> &[Value] {
        match *self {
            Value::Tuple(ref tuple) => &*tuple,
            _ => panic!("Cannot convert this to tuple: {:?}", self),
        }
    }
    pub fn to_f64(&self) -> Option<f64> {
        match *self {
            Value::Float(float) => Some(float as f64),
            _ => None,
        }
    }
    pub fn to_i64(&self) -> Option<i64> {
        match *self {
            Value::Float(float) => {
                let result = float as i64;
                if float == (result as f64) {
                    Some(result)
                } else {
                    None
                }
            }
            _ => None,
        }
    }
    pub fn to_usize(&self) -> Option<usize> {
        match *self {
            Value::Float(float) => {
                let result = float as usize;
                if float == (result as f64) {
                    Some(result)
                } else {
                    None
                }
            },
            _ => None,
        }
    }
}<|endoftext|>