<commit_before>use serde_json;
use std::collections::{HashSet, HashMap};
use std::f64::consts::PI;
use std::fmt;

const PRECISION: f64 = 10000.0;

/// Point containing latitude and longitude values as integers.
/// Integers are used here due to Rust itself not providing some basic
/// floating point functionality at the moment. All due to the undefined
/// behavior revolving around `NaN` float values. For example, what is the boolean
/// result of `0.0 > NaN` ? Its undefined, so therefore > is not implemented by
/// Rust Proper! Perhaps they'll fix this massive inconvienence in the future.
/// TODO use floats
#[derive(PartialEq, Eq, Clone, Debug, Hash, Copy)]
pub struct Point {
    lat: i64,
    lon: i64,
}

/// Degress to Radians
fn deg2rad(deg: f64) -> f64 {
    ((2.0 * PI) / 180.0) * deg
}

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.lat(), self.lon())
    }
}

impl Point {
    /// New integer stored Point from floating point lat/lon coordinates
    pub fn new(lat: f64, lon: f64) -> Point {
        Point {
            lat: (lat * PRECISION).floor() as i64,
            lon: (lon * PRECISION).floor() as i64,
        }
    }

    /// Latitude value
    pub fn lat(&self) -> f64 {
        (self.lat as f64) / PRECISION
    }

    /// Longitude value
    pub fn lon(&self) -> f64 {
        (self.lon as f64) / PRECISION
    }

    /// Spheroid distance calculation given earth coordinates as lat/lon values.
    /// Returns the distance in meters.
    pub fn geo_distance(&self, p: &Point) -> f64 {
        let r = 6371000.0; // metres
        let lat1 = p.lat();
        let lon1 = p.lon();
        let lat2 = self.lat();
        let lon2 = self.lon();
        let sig1 = deg2rad(lat1);
        let sig2 = deg2rad(lat2);
        let deltasig = deg2rad(lat2 - lat1);
        let deltalambda = deg2rad(lon2 - lon1);
        let a = (deltasig / 2.0).sin() * (deltasig / 2.0).sin() +
            sig1.cos() * sig2.cos() *
            (deltalambda / 2.0).sin() * (deltalambda / 2.0).sin();
        let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
        r * c
    }

}

/// Path
pub type Path = Vec<Point>;

/// Maintains a sparse routing graph
#[derive(Default)]
pub struct RouteGraph {
    vertices: HashSet<Point>,
    edges: HashMap<Point, Vec<Point>>,
    paths: HashMap<(Point, Point), Path>,
}

/// Convert the TFL lineStrings attribute to a simple flat vectory of paths.
/// lineStrings in TFL data is a JSON array of string values, containing
/// either an array of points or an array of arrays of points, we handle both.
pub fn linestrings_to_paths(line_strings: &[String]) -> Vec<Path> {
    let mut paths : Vec<Path> = Vec::new();
    for line_string in line_strings {
        match serde_json::from_str::<Vec<(f64, f64)>>(&line_string) {
            Ok(raw_path) => paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect()),
            Err(err) => {
                match serde_json::from_str::<Vec<Vec<(f64, f64)>>>(&line_string) {
                    Ok(raw_paths) => {
                        for raw_path in raw_paths {
                            paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect());
                        }
                    },
                    Err(err2) => println!("Errors decoding line string, single line {}, multi line {}", err, err2),
                }
            },
        }
    }
    paths
}

impl RouteGraph {
    /// New Route Graph
    pub fn new() -> RouteGraph {
        RouteGraph {
            vertices: HashSet::new(),
            edges: HashMap::new(),
            paths: HashMap::new(),
        }
    }

    /// Add many paths
    pub fn add_paths(&mut self, paths: &[Path]) {
        for path in paths {
            self.add_path(path);
        }
    }

    /// Add single path to the graph
    pub fn add_path(&mut self, path: &Path) {
        // add points
        let first = path.first().unwrap();
        let last = path.last().unwrap();
        self.vertices.insert(*first);
        self.vertices.insert(*last);

        // add bidirectional edges
        self.edges.entry(*first).or_insert(vec![*last]).push(*last);
        self.edges.entry(*last).or_insert(vec![*first]).push(*first);

        // add paths
        self.paths.insert((*first, *last), path.clone());
        self.paths.insert((*last, *first), path.iter().rev().cloned().collect());
        assert!(self.paths.contains_key(&(first.clone(), last.clone())));
        assert!(self.paths.contains_key(&(last.clone(), first.clone())));
    }

    /// Find the closest actual point (vertex) in our graph since they are not
    /// going to be exact matches
    fn closest_point(&self, pt: &Point) -> (Point, f64) {
        let far_pt = Point::new(pt.lat() + 90.0, pt.lon() + 90.0);
        let far_dist = far_pt.geo_distance(pt);
        let (min_pt, min_dist) = self.edges.keys().fold((&far_pt, far_dist), |(min_pt, min_dist), vert| {
            let vert_dist = vert.geo_distance(pt);
            if vert_dist < min_dist {
                (vert, vert_dist)
            } else {
                (min_pt, min_dist)
            }
        });

        (*min_pt, min_dist)
    }

    /// Find a path between two points if one exists
    pub fn path(&self, p0: Point, p1: Point) -> Option<Path> {
        let (start, start_dist) = self.closest_point(&p0);
        if start_dist > 2000.0 {
            println!("start point {} to closest {} distance is {} > 2000", p0, start, start_dist);
            return None;
        }
        let (end, end_dist) = self.closest_point(&p1);
        if end_dist > 2000.0 {
            println!("end point {} to closest {} distance is {} > 2000", p1, end, end_dist);
            return None;
        }
        let visited: HashSet<Point> = HashSet::new();
        self.find_path(start, end, &visited)
    }

    // Recursively search the path graph from p0 to p1, when a path is found
    // the callstack will inherently build up a single Path containing all the
    // points between the two.
    // Visited is a simple HashSet marking points we've already visited to avoid
    // infinitely recursing in circles.
    fn find_path(&self, p0: Point, p1: Point, visited: &HashSet<Point>) -> Option<Path> {
        match self.edges.get(&p0) {
            Some(to_vertices) => {
                if visited.contains(&p0) {
                    None
                } else {
                    for next in to_vertices {
                        if *next == p1 {
                            return Some(self.paths.get(&(p0, *next)).unwrap().clone());
                        }

                        let mut visited0 = visited.clone();
                        visited0.insert(*next);

                        if let Some(path) = self.find_path(*next, p1, &visited0) {
                            return Some(vec![&(self.paths.get(&(p0, *next)).unwrap())[..], &path[..]].concat());
                        }
                    }

                    None
                }
            },
            None => None,
        }
    }
}
<commit_msg>Change or_insert with or_insert_with<commit_after>use serde_json;
use std::collections::{HashSet, HashMap};
use std::f64::consts::PI;
use std::fmt;

const PRECISION: f64 = 10000.0;

/// Point containing latitude and longitude values as integers.
/// Integers are used here due to Rust itself not providing some basic
/// floating point functionality at the moment. All due to the undefined
/// behavior revolving around `NaN` float values. For example, what is the boolean
/// result of `0.0 > NaN` ? Its undefined, so therefore > is not implemented by
/// Rust Proper! Perhaps they'll fix this massive inconvienence in the future.
/// TODO use floats
#[derive(PartialEq, Eq, Clone, Debug, Hash, Copy)]
pub struct Point {
    lat: i64,
    lon: i64,
}

/// Degress to Radians
fn deg2rad(deg: f64) -> f64 {
    ((2.0 * PI) / 180.0) * deg
}

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.lat(), self.lon())
    }
}

impl Point {
    /// New integer stored Point from floating point lat/lon coordinates
    pub fn new(lat: f64, lon: f64) -> Point {
        Point {
            lat: (lat * PRECISION).floor() as i64,
            lon: (lon * PRECISION).floor() as i64,
        }
    }

    /// Latitude value
    pub fn lat(&self) -> f64 {
        (self.lat as f64) / PRECISION
    }

    /// Longitude value
    pub fn lon(&self) -> f64 {
        (self.lon as f64) / PRECISION
    }

    /// Spheroid distance calculation given earth coordinates as lat/lon values.
    /// Returns the distance in meters.
    pub fn geo_distance(&self, p: &Point) -> f64 {
        let r = 6371000.0; // metres
        let lat1 = p.lat();
        let lon1 = p.lon();
        let lat2 = self.lat();
        let lon2 = self.lon();
        let sig1 = deg2rad(lat1);
        let sig2 = deg2rad(lat2);
        let deltasig = deg2rad(lat2 - lat1);
        let deltalambda = deg2rad(lon2 - lon1);
        let a = (deltasig / 2.0).sin() * (deltasig / 2.0).sin() +
            sig1.cos() * sig2.cos() *
            (deltalambda / 2.0).sin() * (deltalambda / 2.0).sin();
        let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
        r * c
    }

}

/// Path
pub type Path = Vec<Point>;

/// Maintains a sparse routing graph
#[derive(Default)]
pub struct RouteGraph {
    vertices: HashSet<Point>,
    edges: HashMap<Point, Vec<Point>>,
    paths: HashMap<(Point, Point), Path>,
}

/// Convert the TFL lineStrings attribute to a simple flat vectory of paths.
/// lineStrings in TFL data is a JSON array of string values, containing
/// either an array of points or an array of arrays of points, we handle both.
pub fn linestrings_to_paths(line_strings: &[String]) -> Vec<Path> {
    let mut paths : Vec<Path> = Vec::new();
    for line_string in line_strings {
        match serde_json::from_str::<Vec<(f64, f64)>>(&line_string) {
            Ok(raw_path) => paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect()),
            Err(err) => {
                match serde_json::from_str::<Vec<Vec<(f64, f64)>>>(&line_string) {
                    Ok(raw_paths) => {
                        for raw_path in raw_paths {
                            paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect());
                        }
                    },
                    Err(err2) => println!("Errors decoding line string, single line {}, multi line {}", err, err2),
                }
            },
        }
    }
    paths
}

impl RouteGraph {
    /// New Route Graph
    pub fn new() -> RouteGraph {
        RouteGraph {
            vertices: HashSet::new(),
            edges: HashMap::new(),
            paths: HashMap::new(),
        }
    }

    /// Add many paths
    pub fn add_paths(&mut self, paths: &[Path]) {
        for path in paths {
            self.add_path(path);
        }
    }

    /// Add single path to the graph
    pub fn add_path(&mut self, path: &Path) {
        // add points
        let first = path.first().unwrap();
        let last = path.last().unwrap();
        self.vertices.insert(*first);
        self.vertices.insert(*last);

        // add bidirectional edges
        self.edges.entry(*first).or_insert_with(|| vec![*last]).push(*last);
        self.edges.entry(*last).or_insert_with(|| vec![*first]).push(*first);

        // add paths
        self.paths.insert((*first, *last), path.clone());
        self.paths.insert((*last, *first), path.iter().rev().cloned().collect());
        assert!(self.paths.contains_key(&(first.clone(), last.clone())));
        assert!(self.paths.contains_key(&(last.clone(), first.clone())));
    }

    /// Find the closest actual point (vertex) in our graph since they are not
    /// going to be exact matches
    fn closest_point(&self, pt: &Point) -> (Point, f64) {
        let far_pt = Point::new(pt.lat() + 90.0, pt.lon() + 90.0);
        let far_dist = far_pt.geo_distance(pt);
        let (min_pt, min_dist) = self.edges.keys().fold((&far_pt, far_dist), |(min_pt, min_dist), vert| {
            let vert_dist = vert.geo_distance(pt);
            if vert_dist < min_dist {
                (vert, vert_dist)
            } else {
                (min_pt, min_dist)
            }
        });

        (*min_pt, min_dist)
    }

    /// Find a path between two points if one exists
    pub fn path(&self, p0: Point, p1: Point) -> Option<Path> {
        let (start, start_dist) = self.closest_point(&p0);
        if start_dist > 2000.0 {
            println!("start point {} to closest {} distance is {} > 2000", p0, start, start_dist);
            return None;
        }
        let (end, end_dist) = self.closest_point(&p1);
        if end_dist > 2000.0 {
            println!("end point {} to closest {} distance is {} > 2000", p1, end, end_dist);
            return None;
        }
        let visited: HashSet<Point> = HashSet::new();
        self.find_path(start, end, &visited)
    }

    // Recursively search the path graph from p0 to p1, when a path is found
    // the callstack will inherently build up a single Path containing all the
    // points between the two.
    // Visited is a simple HashSet marking points we've already visited to avoid
    // infinitely recursing in circles.
    fn find_path(&self, p0: Point, p1: Point, visited: &HashSet<Point>) -> Option<Path> {
        match self.edges.get(&p0) {
            Some(to_vertices) => {
                if visited.contains(&p0) {
                    None
                } else {
                    for next in to_vertices {
                        if *next == p1 {
                            return Some(self.paths.get(&(p0, *next)).unwrap().clone());
                        }

                        let mut visited0 = visited.clone();
                        visited0.insert(*next);

                        if let Some(path) = self.find_path(*next, p1, &visited0) {
                            return Some(vec![&(self.paths.get(&(p0, *next)).unwrap())[..], &path[..]].concat());
                        }
                    }

                    None
                }
            },
            None => None,
        }
    }
}
<|endoftext|>


<commit_before>use crate::vm::{Code, VM};
use dora_parser::interner::Name;

#[cfg(target_os = "linux")]
pub fn register_with_perf(code: &Code, vm: &VM, name: Name) {
    use std::fs::OpenOptions;
    use std::io::prelude::*;

    let pid = unsafe { libc::getpid() };
    let fname = format!("/tmp/perf-{}.map", pid);

    let mut options = OpenOptions::new();
    let mut file = options.create(true).append(true).open(&fname).unwrap();

    let code_start = code.ptr_start().to_usize();
    let code_end = code.ptr_end().to_usize();
    let name = vm.interner.str(name);

    let line = format!(
        "{:x} {:x} dora::{}\n",
        code_start,
        code_end - code_start,
        name
    );
    file.write_all(line.as_bytes()).unwrap();
}

#[cfg(not(target_os = "linux"))]
pub fn register_with_perf(_: &Code, _: &VM, _: Name) {
    // nothing to do
}
<commit_msg>fix linux build<commit_after>use crate::vm::{Code, VM};
use dora_parser::interner::Name;

#[cfg(target_os = "linux")]
pub fn register_with_perf(code: &Code, vm: &VM, name: Name) {
    use std::fs::OpenOptions;
    use std::io::prelude::*;

    let pid = unsafe { libc::getpid() };
    let fname = format!("/tmp/perf-{}.map", pid);

    let mut options = OpenOptions::new();
    let mut file = options.create(true).append(true).open(&fname).unwrap();

    let code_start = code.instruction_start().to_usize();
    let code_end = code.instruction_end().to_usize();
    let name = vm.interner.str(name);

    let line = format!(
        "{:x} {:x} dora::{}\n",
        code_start,
        code_end - code_start,
        name
    );
    file.write_all(line.as_bytes()).unwrap();
}

#[cfg(not(target_os = "linux"))]
pub fn register_with_perf(_: &Code, _: &VM, _: Name) {
    // nothing to do
}
<|endoftext|>


<commit_before>//! A system for creating and managing multiple connections to IRC servers.

use client::data::Config;
use client::server::{IrcServer, IrcServerFuture, Server};
use error;
use proto::Message;

use futures::{Future, Stream};
use futures::future;
use tokio_core::reactor::Core;

pub struct IrcReactor {
    inner: Core,
    handlers: Vec<Box<Future<Item = (), Error = error::Error>>>,
}

impl IrcReactor {
    pub fn new() -> error::Result<IrcReactor> {
        Ok(IrcReactor {
            inner: Core::new()?,
            handlers: Vec::new(),
        })
    }

    pub fn prepare_server<'a>(&mut self, config: &'a Config) -> error::Result<IrcServerFuture<'a>> {
        IrcServer::new_future(self.inner.handle(), config)
    }

    pub fn connect_server(&mut self, future: IrcServerFuture) -> error::Result<IrcServer> {
        self.inner.run(future)
    }

    pub fn prepare_server_and_connect(&mut self, config: &Config) -> error::Result<IrcServer> {
        self.prepare_server(config).and_then(|future| self.connect_server(future))
    }

    pub fn register_server_with_handler<F>(
        &mut self, server: IrcServer, handler: F
    ) where F: Fn(&IrcServer, Message) -> error::Result<()> + 'static  {
        self.handlers.push(Box::new(server.stream().for_each(move |message| {
            handler(&server, message)
        })));
    }

    pub fn run(&mut self) -> error::Result<()> {
        let mut handlers = Vec::new();
        while let Some(handler) = self.handlers.pop() {
            handlers.push(handler);
        }
        self.inner.run(future::join_all(handlers).map(|_| ()))
    }
}
<commit_msg>Reorganized imports in reactor.rs.<commit_after>//! A system for creating and managing multiple connections to IRC servers.

use futures::{Future, Stream};
use futures::future;
use tokio_core::reactor::Core;

use client::data::Config;
use client::server::{IrcServer, IrcServerFuture, Server};
use error;
use proto::Message;

pub struct IrcReactor {
    inner: Core,
    handlers: Vec<Box<Future<Item = (), Error = error::Error>>>,
}

impl IrcReactor {
    pub fn new() -> error::Result<IrcReactor> {
        Ok(IrcReactor {
            inner: Core::new()?,
            handlers: Vec::new(),
        })
    }

    pub fn prepare_server<'a>(&mut self, config: &'a Config) -> error::Result<IrcServerFuture<'a>> {
        IrcServer::new_future(self.inner.handle(), config)
    }

    pub fn connect_server(&mut self, future: IrcServerFuture) -> error::Result<IrcServer> {
        self.inner.run(future)
    }

    pub fn prepare_server_and_connect(&mut self, config: &Config) -> error::Result<IrcServer> {
        self.prepare_server(config).and_then(|future| self.connect_server(future))
    }

    pub fn register_server_with_handler<F>(
        &mut self, server: IrcServer, handler: F
    ) where F: Fn(&IrcServer, Message) -> error::Result<()> + 'static  {
        self.handlers.push(Box::new(server.stream().for_each(move |message| {
            handler(&server, message)
        })));
    }

    pub fn run(&mut self) -> error::Result<()> {
        let mut handlers = Vec::new();
        while let Some(handler) = self.handlers.pop() {
            handlers.push(handler);
        }
        self.inner.run(future::join_all(handlers).map(|_| ()))
    }
}
<|endoftext|>


<commit_before>use crate::hasher::{Digest, Size};
use crate::Error;
use core::convert::TryFrom;
#[cfg(feature = "std")]
use core::convert::TryInto;
use core::fmt::Debug;
use generic_array::{ArrayLength, GenericArray};

/// Trait that implements hashing.
///
/// It is usually implemented by a custom code table enum that derives the [`Multihash` derive].
///
/// [`Multihash` derive]: crate::derive
pub trait MultihashDigest:
    TryFrom<u64> + Into<u64> + Send + Sync + Unpin + Copy + Eq + Debug + 'static
{
    /// The maximum size a hash will allocate.
    type AllocSize: Size;

    /// Calculate the hash of some input data.
    ///
    /// # Example
    ///
    /// ```
    /// // `Code` implements `MultihashDigest`
    /// use multihash::{Code, MultihashDigest};
    ///
    /// let hash = Code::Sha3_256.digest(b"Hello world!");
    /// println!("{:02x?}", hash);
    /// ```
    fn digest(&self, input: &[u8]) -> Multihash<Self::AllocSize>;

    /// Create a multihash from an existing [`Digest`].
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Code, MultihashDigest, Sha3_256, StatefulHasher};
    ///
    /// let mut hasher = Sha3_256::default();
    /// hasher.update(b"Hello world!");
    /// let hash = Code::multihash_from_digest(&hasher.finalize());
    /// println!("{:02x?}", hash);
    /// ```
    fn multihash_from_digest<'a, S, D>(digest: &'a D) -> Multihash<Self::AllocSize>
    where
        S: Size,
        D: Digest<S>,
        Self: From<&'a D>;
}

/// A Multihash instance that only supports the basic functionality and no hashing.
///
/// With this Multihash implementation you can operate on Multihashes in a generic way, but
/// no hasher implementation is associated with the code.
///
/// # Example
///
/// ```
/// use multihash::{Multihash, U64};
///
/// const Sha3_256: u64 = 0x16;
/// let digest_bytes = [
///     0x16, 0x20, 0x64, 0x4b, 0xcc, 0x7e, 0x56, 0x43, 0x73, 0x04, 0x09, 0x99, 0xaa, 0xc8, 0x9e,
///     0x76, 0x22, 0xf3, 0xca, 0x71, 0xfb, 0xa1, 0xd9, 0x72, 0xfd, 0x94, 0xa3, 0x1c, 0x3b, 0xfb,
///     0xf2, 0x4e, 0x39, 0x38,
/// ];
/// let mh = Multihash::<U64>::from_bytes(&digest_bytes).unwrap();
/// assert_eq!(mh.code(), Sha3_256);
/// assert_eq!(mh.size(), 32);
/// assert_eq!(mh.digest(), &digest_bytes[2..]);
/// ```
#[cfg_attr(feature = "serde-codec", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde-codec", derive(serde::Serialize))]
#[cfg_attr(feature = "serde-codec", serde(bound = "S: Size"))]
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Multihash<S: Size> {
    /// The code of the Multihash.
    code: u64,
    /// The actual size of the digest in bytes (not the allocated size).
    size: u8,
    /// The digest.
    digest: GenericArray<u8, S>,
}

impl<S: Size> Copy for Multihash<S> where <S as ArrayLength<u8>>::ArrayType: Copy {}

impl<S: Size> Multihash<S> {
    /// Wraps the digest in a multihash.
    pub fn wrap(code: u64, input_digest: &[u8]) -> Result<Self, Error> {
        if input_digest.len() > S::to_usize() {
            return Err(Error::InvalidSize(input_digest.len() as _));
        }
        let size = input_digest.len();
        let mut digest = GenericArray::default();
        digest[..size].copy_from_slice(input_digest);
        Ok(Self {
            code,
            size: size as u8,
            digest,
        })
    }

    /// Returns the code of the multihash.
    pub fn code(&self) -> u64 {
        self.code
    }

    /// Returns the size of the digest.
    pub fn size(&self) -> u8 {
        self.size
    }

    /// Returns the digest.
    pub fn digest(&self) -> &[u8] {
        &self.digest[..self.size as usize]
    }

    /// Reads a multihash from a byte stream.
    #[cfg(feature = "std")]
    pub fn read<R: std::io::Read>(r: R) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let (code, size, digest) = read_multihash(r)?;
        Ok(Self { code, size, digest })
    }

    /// Parses a multihash from a bytes.
    ///
    /// You need to make sure the passed in bytes have the correct length. The digest length
    /// needs to match the `size` value of the multihash.
    #[cfg(feature = "std")]
    pub fn from_bytes(mut bytes: &[u8]) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let result = Self::read(&mut bytes)?;
        // There were more bytes supplied than read
        if !bytes.is_empty() {
            return Err(Error::InvalidSize(bytes.len().try_into().expect(
                "Currently the maximum size is 255, therefore always fits into usize",
            )));
        }

        Ok(result)
    }

    /// Writes a multihash to a byte stream.
    #[cfg(feature = "std")]
    pub fn write<W: std::io::Write>(&self, w: W) -> Result<(), Error> {
        write_multihash(w, self.code(), self.size(), self.digest())
    }

    /// Returns the bytes of a multihash.
    #[cfg(feature = "std")]
    pub fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(self.size().into());
        self.write(&mut bytes)
            .expect("writing to a vec should never fail");
        bytes
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Encode for Multihash<crate::U32> {
    fn encode_to<EncOut: parity_scale_codec::Output>(&self, dest: &mut EncOut) {
        let mut digest = [0; 32];
        digest.copy_from_slice(&self.digest);
        dest.push(&self.code);
        dest.push(&self.size);
        dest.push(&digest);
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::EncodeLike for Multihash<crate::U32> {}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Decode for Multihash<crate::U32> {
    fn decode<DecIn: parity_scale_codec::Input>(
        input: &mut DecIn,
    ) -> Result<Self, parity_scale_codec::Error> {
        Ok(Multihash {
            code: parity_scale_codec::Decode::decode(input)?,
            size: parity_scale_codec::Decode::decode(input)?,
            digest: {
                let digest = <[u8; 32]>::decode(input)?;
                GenericArray::clone_from_slice(&digest)
            },
        })
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Encode for Multihash<crate::U64> {
    fn encode_to<EncOut: parity_scale_codec::Output>(&self, dest: &mut EncOut) {
        let mut digest = [0; 64];
        digest.copy_from_slice(&self.digest);
        dest.push(&self.code);
        dest.push(&self.size);
        dest.push(&digest);
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::EncodeLike for Multihash<crate::U64> {}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Decode for Multihash<crate::U64> {
    fn decode<DecIn: parity_scale_codec::Input>(
        input: &mut DecIn,
    ) -> Result<Self, parity_scale_codec::Error> {
        Ok(Multihash {
            code: parity_scale_codec::Decode::decode(input)?,
            size: parity_scale_codec::Decode::decode(input)?,
            digest: {
                let digest = <[u8; 64]>::decode(input)?;
                GenericArray::clone_from_slice(&digest)
            },
        })
    }
}

/// Writes the multihash to a byte stream.
#[cfg(feature = "std")]
pub fn write_multihash<W>(mut w: W, code: u64, size: u8, digest: &[u8]) -> Result<(), Error>
where
    W: std::io::Write,
{
    use unsigned_varint::encode as varint_encode;

    let mut code_buf = varint_encode::u64_buffer();
    let code = varint_encode::u64(code, &mut code_buf);

    let mut size_buf = varint_encode::u8_buffer();
    let size = varint_encode::u8(size, &mut size_buf);

    w.write_all(code)?;
    w.write_all(size)?;
    w.write_all(digest)?;
    Ok(())
}

/// Reads a multihash from a byte stream that contains a full multihash (code, size and the digest)
///
/// Returns the code, size and the digest. The size is the actual size and not the
/// maximum/allocated size of the digest.
///
/// Currently the maximum size for a digest is 255 bytes.
#[cfg(feature = "std")]
pub fn read_multihash<R, S>(mut r: R) -> Result<(u64, u8, GenericArray<u8, S>), Error>
where
    R: std::io::Read,
    S: Size,
{
    use unsigned_varint::io::read_u64;

    let code = read_u64(&mut r)?;
    let size = read_u64(&mut r)?;

    if size > S::to_u64() || size > u8::MAX as u64 {
        return Err(Error::InvalidSize(size));
    }

    let mut digest = GenericArray::default();
    r.read_exact(&mut digest[..size as usize])?;
    Ok((code, size as u8, digest))
}

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

    #[test]
    fn roundtrip() {
        let hash = Code::Sha2_256.digest(b"hello world");
        let mut buf = [0u8; 35];
        hash.write(&mut buf[..]).unwrap();
        let hash2 = Multihash::read(&buf[..]).unwrap();
        assert_eq!(hash, hash2);
    }

    #[test]
    #[cfg(feature = "scale-codec")]
    fn test_scale() {
        use parity_scale_codec::{Decode, Encode};

        let mh = Multihash::<crate::U32>::default();
        let bytes = mh.encode();
        let mh2: Multihash<crate::U32> = Decode::decode(&mut &bytes[..]).unwrap();
        assert_eq!(mh, mh2);
    }

    #[test]
    #[cfg(feature = "serde-codec")]
    fn test_serde() {
        let mh = Multihash::<crate::U32>::default();
        let bytes = serde_json::to_string(&mh).unwrap();
        let mh2 = serde_json::from_str(&bytes).unwrap();
        assert_eq!(mh, mh2);
    }
}
<commit_msg>feat: add Multihash to Vec<u8> conversion<commit_after>use crate::hasher::{Digest, Size};
use crate::Error;
use core::convert::TryFrom;
#[cfg(feature = "std")]
use core::convert::TryInto;
use core::fmt::Debug;
use generic_array::{ArrayLength, GenericArray};

/// Trait that implements hashing.
///
/// It is usually implemented by a custom code table enum that derives the [`Multihash` derive].
///
/// [`Multihash` derive]: crate::derive
pub trait MultihashDigest:
    TryFrom<u64> + Into<u64> + Send + Sync + Unpin + Copy + Eq + Debug + 'static
{
    /// The maximum size a hash will allocate.
    type AllocSize: Size;

    /// Calculate the hash of some input data.
    ///
    /// # Example
    ///
    /// ```
    /// // `Code` implements `MultihashDigest`
    /// use multihash::{Code, MultihashDigest};
    ///
    /// let hash = Code::Sha3_256.digest(b"Hello world!");
    /// println!("{:02x?}", hash);
    /// ```
    fn digest(&self, input: &[u8]) -> Multihash<Self::AllocSize>;

    /// Create a multihash from an existing [`Digest`].
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Code, MultihashDigest, Sha3_256, StatefulHasher};
    ///
    /// let mut hasher = Sha3_256::default();
    /// hasher.update(b"Hello world!");
    /// let hash = Code::multihash_from_digest(&hasher.finalize());
    /// println!("{:02x?}", hash);
    /// ```
    fn multihash_from_digest<'a, S, D>(digest: &'a D) -> Multihash<Self::AllocSize>
    where
        S: Size,
        D: Digest<S>,
        Self: From<&'a D>;
}

/// A Multihash instance that only supports the basic functionality and no hashing.
///
/// With this Multihash implementation you can operate on Multihashes in a generic way, but
/// no hasher implementation is associated with the code.
///
/// # Example
///
/// ```
/// use multihash::{Multihash, U64};
///
/// const Sha3_256: u64 = 0x16;
/// let digest_bytes = [
///     0x16, 0x20, 0x64, 0x4b, 0xcc, 0x7e, 0x56, 0x43, 0x73, 0x04, 0x09, 0x99, 0xaa, 0xc8, 0x9e,
///     0x76, 0x22, 0xf3, 0xca, 0x71, 0xfb, 0xa1, 0xd9, 0x72, 0xfd, 0x94, 0xa3, 0x1c, 0x3b, 0xfb,
///     0xf2, 0x4e, 0x39, 0x38,
/// ];
/// let mh = Multihash::<U64>::from_bytes(&digest_bytes).unwrap();
/// assert_eq!(mh.code(), Sha3_256);
/// assert_eq!(mh.size(), 32);
/// assert_eq!(mh.digest(), &digest_bytes[2..]);
/// ```
#[cfg_attr(feature = "serde-codec", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde-codec", derive(serde::Serialize))]
#[cfg_attr(feature = "serde-codec", serde(bound = "S: Size"))]
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Multihash<S: Size> {
    /// The code of the Multihash.
    code: u64,
    /// The actual size of the digest in bytes (not the allocated size).
    size: u8,
    /// The digest.
    digest: GenericArray<u8, S>,
}

impl<S: Size> Copy for Multihash<S> where <S as ArrayLength<u8>>::ArrayType: Copy {}

impl<S: Size> Multihash<S> {
    /// Wraps the digest in a multihash.
    pub fn wrap(code: u64, input_digest: &[u8]) -> Result<Self, Error> {
        if input_digest.len() > S::to_usize() {
            return Err(Error::InvalidSize(input_digest.len() as _));
        }
        let size = input_digest.len();
        let mut digest = GenericArray::default();
        digest[..size].copy_from_slice(input_digest);
        Ok(Self {
            code,
            size: size as u8,
            digest,
        })
    }

    /// Returns the code of the multihash.
    pub fn code(&self) -> u64 {
        self.code
    }

    /// Returns the size of the digest.
    pub fn size(&self) -> u8 {
        self.size
    }

    /// Returns the digest.
    pub fn digest(&self) -> &[u8] {
        &self.digest[..self.size as usize]
    }

    /// Reads a multihash from a byte stream.
    #[cfg(feature = "std")]
    pub fn read<R: std::io::Read>(r: R) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let (code, size, digest) = read_multihash(r)?;
        Ok(Self { code, size, digest })
    }

    /// Parses a multihash from a bytes.
    ///
    /// You need to make sure the passed in bytes have the correct length. The digest length
    /// needs to match the `size` value of the multihash.
    #[cfg(feature = "std")]
    pub fn from_bytes(mut bytes: &[u8]) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let result = Self::read(&mut bytes)?;
        // There were more bytes supplied than read
        if !bytes.is_empty() {
            return Err(Error::InvalidSize(bytes.len().try_into().expect(
                "Currently the maximum size is 255, therefore always fits into usize",
            )));
        }

        Ok(result)
    }

    /// Writes a multihash to a byte stream.
    #[cfg(feature = "std")]
    pub fn write<W: std::io::Write>(&self, w: W) -> Result<(), Error> {
        write_multihash(w, self.code(), self.size(), self.digest())
    }

    /// Returns the bytes of a multihash.
    #[cfg(feature = "std")]
    pub fn to_bytes(&self) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(self.size().into());
        self.write(&mut bytes)
            .expect("writing to a vec should never fail");
        bytes
    }
}

#[cfg(feature = "std")]
impl<S: Size> From<Multihash<S>> for Vec<u8> {
    fn from(multihash: Multihash<S>) -> Self {
        multihash.to_bytes()
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Encode for Multihash<crate::U32> {
    fn encode_to<EncOut: parity_scale_codec::Output>(&self, dest: &mut EncOut) {
        let mut digest = [0; 32];
        digest.copy_from_slice(&self.digest);
        dest.push(&self.code);
        dest.push(&self.size);
        dest.push(&digest);
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::EncodeLike for Multihash<crate::U32> {}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Decode for Multihash<crate::U32> {
    fn decode<DecIn: parity_scale_codec::Input>(
        input: &mut DecIn,
    ) -> Result<Self, parity_scale_codec::Error> {
        Ok(Multihash {
            code: parity_scale_codec::Decode::decode(input)?,
            size: parity_scale_codec::Decode::decode(input)?,
            digest: {
                let digest = <[u8; 32]>::decode(input)?;
                GenericArray::clone_from_slice(&digest)
            },
        })
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Encode for Multihash<crate::U64> {
    fn encode_to<EncOut: parity_scale_codec::Output>(&self, dest: &mut EncOut) {
        let mut digest = [0; 64];
        digest.copy_from_slice(&self.digest);
        dest.push(&self.code);
        dest.push(&self.size);
        dest.push(&digest);
    }
}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::EncodeLike for Multihash<crate::U64> {}

#[cfg(feature = "scale-codec")]
impl parity_scale_codec::Decode for Multihash<crate::U64> {
    fn decode<DecIn: parity_scale_codec::Input>(
        input: &mut DecIn,
    ) -> Result<Self, parity_scale_codec::Error> {
        Ok(Multihash {
            code: parity_scale_codec::Decode::decode(input)?,
            size: parity_scale_codec::Decode::decode(input)?,
            digest: {
                let digest = <[u8; 64]>::decode(input)?;
                GenericArray::clone_from_slice(&digest)
            },
        })
    }
}

/// Writes the multihash to a byte stream.
#[cfg(feature = "std")]
pub fn write_multihash<W>(mut w: W, code: u64, size: u8, digest: &[u8]) -> Result<(), Error>
where
    W: std::io::Write,
{
    use unsigned_varint::encode as varint_encode;

    let mut code_buf = varint_encode::u64_buffer();
    let code = varint_encode::u64(code, &mut code_buf);

    let mut size_buf = varint_encode::u8_buffer();
    let size = varint_encode::u8(size, &mut size_buf);

    w.write_all(code)?;
    w.write_all(size)?;
    w.write_all(digest)?;
    Ok(())
}

/// Reads a multihash from a byte stream that contains a full multihash (code, size and the digest)
///
/// Returns the code, size and the digest. The size is the actual size and not the
/// maximum/allocated size of the digest.
///
/// Currently the maximum size for a digest is 255 bytes.
#[cfg(feature = "std")]
pub fn read_multihash<R, S>(mut r: R) -> Result<(u64, u8, GenericArray<u8, S>), Error>
where
    R: std::io::Read,
    S: Size,
{
    use unsigned_varint::io::read_u64;

    let code = read_u64(&mut r)?;
    let size = read_u64(&mut r)?;

    if size > S::to_u64() || size > u8::MAX as u64 {
        return Err(Error::InvalidSize(size));
    }

    let mut digest = GenericArray::default();
    r.read_exact(&mut digest[..size as usize])?;
    Ok((code, size as u8, digest))
}

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

    #[test]
    fn roundtrip() {
        let hash = Code::Sha2_256.digest(b"hello world");
        let mut buf = [0u8; 35];
        hash.write(&mut buf[..]).unwrap();
        let hash2 = Multihash::read(&buf[..]).unwrap();
        assert_eq!(hash, hash2);
    }

    #[test]
    #[cfg(feature = "scale-codec")]
    fn test_scale() {
        use parity_scale_codec::{Decode, Encode};

        let mh = Multihash::<crate::U32>::default();
        let bytes = mh.encode();
        let mh2: Multihash<crate::U32> = Decode::decode(&mut &bytes[..]).unwrap();
        assert_eq!(mh, mh2);
    }

    #[test]
    #[cfg(feature = "serde-codec")]
    fn test_serde() {
        let mh = Multihash::<crate::U32>::default();
        let bytes = serde_json::to_string(&mh).unwrap();
        let mh2 = serde_json::from_str(&bytes).unwrap();
        assert_eq!(mh, mh2);
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use fbo::{self, FramebufferAttachments};

use DisplayImpl;
use Surface;

use gl;

pub fn clear(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
             color: Option<(f32, f32, f32, f32)>, depth: Option<f32>, stencil: Option<i32>)
{
    let color = color.map(|(red, green, blue, alpha)| (
        red as gl::types::GLclampf,
        green as gl::types::GLclampf,
        blue as gl::types::GLclampf,
        alpha as gl::types::GLclampf
    ));

    let depth = depth.map(|value| value as gl::types::GLclampf);
    let stencil = stencil.map(|value| value as gl::types::GLint);

    let flags = if color.is_some() { gl::COLOR_BUFFER_BIT } else { 0 } |
                if depth.is_some() { gl::DEPTH_BUFFER_BIT } else { 0 } |
                if stencil.is_some() { gl::STENCIL_BUFFER_BIT } else { 0 };

    let fbo_id = display.framebuffer_objects.as_ref().unwrap()
                        .get_framebuffer_for_drawing(framebuffer, &display.context);

    display.context.exec(move |mut ctxt| {
        fbo::bind_framebuffer(&mut ctxt, fbo_id, true, false);

        unsafe {
            if ctxt.state.enabled_rasterizer_discard {
                ctxt.gl.Disable(gl::RASTERIZER_DISCARD);
                ctxt.state.enabled_rasterizer_discard = false;
            }

            if ctxt.state.enabled_scissor_test {
                ctxt.gl.Disable(gl::SCISSOR_TEST);
                ctxt.state.enabled_scissor_test = false;
            }

            if let Some(color) = color {
                if ctxt.state.clear_color != color {
                    ctxt.gl.ClearColor(color.0, color.1, color.2, color.3);
                    ctxt.state.clear_color = color;
                }
            }

            if let Some(depth) = depth {
                if ctxt.state.clear_depth != depth {
                    ctxt.gl.ClearDepth(depth as f64);        // TODO: find out why this needs "as"
                    ctxt.state.clear_depth = depth;
                }
            }

            if let Some(stencil) = stencil {
                if ctxt.state.clear_stencil != stencil {
                    ctxt.gl.ClearStencil(stencil);
                    ctxt.state.clear_stencil = stencil;
                }
            }

            ctxt.gl.Clear(flags);
        }
    });
}
<commit_msg>Fix clear_depth not working after drawing with depth_write = false<commit_after>use std::sync::Arc;

use fbo::{self, FramebufferAttachments};

use DisplayImpl;
use Surface;

use gl;

pub fn clear(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
             color: Option<(f32, f32, f32, f32)>, depth: Option<f32>, stencil: Option<i32>)
{
    let color = color.map(|(red, green, blue, alpha)| (
        red as gl::types::GLclampf,
        green as gl::types::GLclampf,
        blue as gl::types::GLclampf,
        alpha as gl::types::GLclampf
    ));

    let depth = depth.map(|value| value as gl::types::GLclampf);
    let stencil = stencil.map(|value| value as gl::types::GLint);

    let flags = if color.is_some() { gl::COLOR_BUFFER_BIT } else { 0 } |
                if depth.is_some() { gl::DEPTH_BUFFER_BIT } else { 0 } |
                if stencil.is_some() { gl::STENCIL_BUFFER_BIT } else { 0 };

    let fbo_id = display.framebuffer_objects.as_ref().unwrap()
                        .get_framebuffer_for_drawing(framebuffer, &display.context);

    display.context.exec(move |mut ctxt| {
        fbo::bind_framebuffer(&mut ctxt, fbo_id, true, false);

        unsafe {
            if ctxt.state.enabled_rasterizer_discard {
                ctxt.gl.Disable(gl::RASTERIZER_DISCARD);
                ctxt.state.enabled_rasterizer_discard = false;
            }

            if ctxt.state.enabled_scissor_test {
                ctxt.gl.Disable(gl::SCISSOR_TEST);
                ctxt.state.enabled_scissor_test = false;
            }

            if let Some(color) = color {
                if ctxt.state.clear_color != color {
                    ctxt.gl.ClearColor(color.0, color.1, color.2, color.3);
                    ctxt.state.clear_color = color;
                }
            }

            if let Some(depth) = depth {
                if ctxt.state.clear_depth != depth {
                    ctxt.gl.ClearDepth(depth as f64);        // TODO: find out why this needs "as"
                    ctxt.state.clear_depth = depth;
                }

                if !ctxt.state.depth_mask {
                    ctxt.gl.DepthMask(gl::TRUE);
                    ctxt.state.depth_mask = true;
                }
            }

            if let Some(stencil) = stencil {
                if ctxt.state.clear_stencil != stencil {
                    ctxt.gl.ClearStencil(stencil);
                    ctxt.state.clear_stencil = stencil;
                }
            }

            ctxt.gl.Clear(flags);
        }
    });
}
<|endoftext|>


<commit_before>use std::num::NonZeroU8;
use std::{fmt, ops};

/// Interest used in registering.
///
/// Interest are used in [registering] [`event::Source`]s with [`Poll`], they
/// indicate what readiness should be monitored for. For example if a socket is
/// registered with [readable] interests and the socket becomes writable, no
/// event will be returned from a call to [`poll`].
///
/// [registering]: struct.Registry.html#method.reregister
/// [`event::Source`]: ./event/trait.Source.html
/// [`Poll`]: struct.Poll.html
/// [readable]: struct.Interest.html#associatedconstant.READABLE
/// [`poll`]: struct.Poll.html#method.poll
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct Interest(NonZeroU8);

// These must be unique.
const READABLE: u8 = 0b0_001;
const WRITABLE: u8 = 0b0_010;
// The following are not available on all platforms.
#[cfg_attr(
    not(any(
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "ios",
        target_os = "macos"
    )),
    allow(dead_code)
)]
const AIO: u8 = 0b0_100;
#[cfg_attr(not(target_os = "freebsd"), allow(dead_code))]
const LIO: u8 = 0b1_000;

impl Interest {
    /// Returns a `Interest` set representing readable interests.
    pub const READABLE: Interest = Interest(unsafe { NonZeroU8::new_unchecked(READABLE) });

    /// Returns a `Interest` set representing writable interests.
    pub const WRITABLE: Interest = Interest(unsafe { NonZeroU8::new_unchecked(WRITABLE) });

    /// Returns a `Interest` set representing AIO completion interests.
    #[cfg(any(
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "ios",
        target_os = "macos"
    ))]
    pub const AIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(AIO) });

    /// Returns a `Interest` set representing LIO completion interests.
    #[cfg(target_os = "freebsd")]
    pub const LIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(LIO) });

    /// Add together two `Interest`.
    ///
    /// This does the same thing as the `BitOr` implementation, but is a
    /// constant function.
    ///
    /// ```
    /// use mio::Interest;
    ///
    /// const INTERESTS: Interest = Interest::READABLE.add(Interest::WRITABLE);
    /// # fn silent_dead_code_warning(_: Interest) { }
    /// # silent_dead_code_warning(INTERESTS)
    /// ```
    #[allow(clippy::should_implement_trait)]
    pub const fn add(self, other: Interest) -> Interest {
        Interest(unsafe { NonZeroU8::new_unchecked(self.0.get() | other.0.get()) })
    }

    /// Removes `other` `Interest` from `self`.
    ///
    /// Returns `None` if the set would be empty after removing `other`.
    ///
    /// ```
    /// use mio::Interest;
    ///
    /// const RW_INTERESTS: Interest = Interest::READABLE.add(Interest::WRITABLE);
    ///
    /// // As long a one interest remain this will return `Some`.
    /// let w_interest = RW_INTERESTS.remove(Interest::READABLE).unwrap();
    /// assert!(!w_interest.is_readable());
    /// assert!(w_interest.is_writable());
    ///
    /// // Removing all interests from the set will return `None`.
    /// assert_eq!(w_interest.remove(Interest::WRITABLE), None);
    ///
    /// // Its also possible to remove multiple interests at once.
    /// assert_eq!(RW_INTERESTS.remove(RW_INTERESTS), None);
    /// ```
    pub fn remove(self, other: Interest) -> Option<Interest> {
        NonZeroU8::new(self.0.get() & !other.0.get()).map(Interest)
    }

    /// Returns true if the value includes readable readiness.
    pub const fn is_readable(self) -> bool {
        (self.0.get() & READABLE) != 0
    }

    /// Returns true if the value includes writable readiness.
    pub const fn is_writable(self) -> bool {
        (self.0.get() & WRITABLE) != 0
    }

    /// Returns true if `Interest` contains AIO readiness
    pub const fn is_aio(self) -> bool {
        (self.0.get() & AIO) != 0
    }

    /// Returns true if `Interest` contains LIO readiness
    pub const fn is_lio(self) -> bool {
        (self.0.get() & LIO) != 0
    }
}

impl ops::BitOr for Interest {
    type Output = Self;

    #[inline]
    fn bitor(self, other: Self) -> Self {
        self.add(other)
    }
}

impl ops::BitOrAssign for Interest {
    #[inline]
    fn bitor_assign(&mut self, other: Self) {
        self.0 = (*self | other).0;
    }
}

impl fmt::Debug for Interest {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut one = false;
        if self.is_readable() {
            if one {
                write!(fmt, " | ")?
            }
            write!(fmt, "READABLE")?;
            one = true
        }
        if self.is_writable() {
            if one {
                write!(fmt, " | ")?
            }
            write!(fmt, "WRITABLE")?;
            one = true
        }
        #[cfg(any(
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "ios",
            target_os = "macos"
        ))]
        {
            if self.is_aio() {
                if one {
                    write!(fmt, " | ")?
                }
                write!(fmt, "AIO")?;
                one = true
            }
        }
        #[cfg(any(target_os = "freebsd"))]
        {
            if self.is_lio() {
                if one {
                    write!(fmt, " | ")?
                }
                write!(fmt, "LIO")?;
                one = true
            }
        }
        debug_assert!(one, "printing empty interests");
        Ok(())
    }
}
<commit_msg>Fix link in Interest (#1365)<commit_after>use std::num::NonZeroU8;
use std::{fmt, ops};

/// Interest used in registering.
///
/// Interest are used in [registering] [`event::Source`]s with [`Poll`], they
/// indicate what readiness should be monitored for. For example if a socket is
/// registered with [readable] interests and the socket becomes writable, no
/// event will be returned from a call to [`poll`].
///
/// [registering]: struct.Registry.html#method.register
/// [`event::Source`]: ./event/trait.Source.html
/// [`Poll`]: struct.Poll.html
/// [readable]: struct.Interest.html#associatedconstant.READABLE
/// [`poll`]: struct.Poll.html#method.poll
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct Interest(NonZeroU8);

// These must be unique.
const READABLE: u8 = 0b0_001;
const WRITABLE: u8 = 0b0_010;
// The following are not available on all platforms.
#[cfg_attr(
    not(any(
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "ios",
        target_os = "macos"
    )),
    allow(dead_code)
)]
const AIO: u8 = 0b0_100;
#[cfg_attr(not(target_os = "freebsd"), allow(dead_code))]
const LIO: u8 = 0b1_000;

impl Interest {
    /// Returns a `Interest` set representing readable interests.
    pub const READABLE: Interest = Interest(unsafe { NonZeroU8::new_unchecked(READABLE) });

    /// Returns a `Interest` set representing writable interests.
    pub const WRITABLE: Interest = Interest(unsafe { NonZeroU8::new_unchecked(WRITABLE) });

    /// Returns a `Interest` set representing AIO completion interests.
    #[cfg(any(
        target_os = "dragonfly",
        target_os = "freebsd",
        target_os = "ios",
        target_os = "macos"
    ))]
    pub const AIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(AIO) });

    /// Returns a `Interest` set representing LIO completion interests.
    #[cfg(target_os = "freebsd")]
    pub const LIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(LIO) });

    /// Add together two `Interest`.
    ///
    /// This does the same thing as the `BitOr` implementation, but is a
    /// constant function.
    ///
    /// ```
    /// use mio::Interest;
    ///
    /// const INTERESTS: Interest = Interest::READABLE.add(Interest::WRITABLE);
    /// # fn silent_dead_code_warning(_: Interest) { }
    /// # silent_dead_code_warning(INTERESTS)
    /// ```
    #[allow(clippy::should_implement_trait)]
    pub const fn add(self, other: Interest) -> Interest {
        Interest(unsafe { NonZeroU8::new_unchecked(self.0.get() | other.0.get()) })
    }

    /// Removes `other` `Interest` from `self`.
    ///
    /// Returns `None` if the set would be empty after removing `other`.
    ///
    /// ```
    /// use mio::Interest;
    ///
    /// const RW_INTERESTS: Interest = Interest::READABLE.add(Interest::WRITABLE);
    ///
    /// // As long a one interest remain this will return `Some`.
    /// let w_interest = RW_INTERESTS.remove(Interest::READABLE).unwrap();
    /// assert!(!w_interest.is_readable());
    /// assert!(w_interest.is_writable());
    ///
    /// // Removing all interests from the set will return `None`.
    /// assert_eq!(w_interest.remove(Interest::WRITABLE), None);
    ///
    /// // Its also possible to remove multiple interests at once.
    /// assert_eq!(RW_INTERESTS.remove(RW_INTERESTS), None);
    /// ```
    pub fn remove(self, other: Interest) -> Option<Interest> {
        NonZeroU8::new(self.0.get() & !other.0.get()).map(Interest)
    }

    /// Returns true if the value includes readable readiness.
    pub const fn is_readable(self) -> bool {
        (self.0.get() & READABLE) != 0
    }

    /// Returns true if the value includes writable readiness.
    pub const fn is_writable(self) -> bool {
        (self.0.get() & WRITABLE) != 0
    }

    /// Returns true if `Interest` contains AIO readiness
    pub const fn is_aio(self) -> bool {
        (self.0.get() & AIO) != 0
    }

    /// Returns true if `Interest` contains LIO readiness
    pub const fn is_lio(self) -> bool {
        (self.0.get() & LIO) != 0
    }
}

impl ops::BitOr for Interest {
    type Output = Self;

    #[inline]
    fn bitor(self, other: Self) -> Self {
        self.add(other)
    }
}

impl ops::BitOrAssign for Interest {
    #[inline]
    fn bitor_assign(&mut self, other: Self) {
        self.0 = (*self | other).0;
    }
}

impl fmt::Debug for Interest {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut one = false;
        if self.is_readable() {
            if one {
                write!(fmt, " | ")?
            }
            write!(fmt, "READABLE")?;
            one = true
        }
        if self.is_writable() {
            if one {
                write!(fmt, " | ")?
            }
            write!(fmt, "WRITABLE")?;
            one = true
        }
        #[cfg(any(
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "ios",
            target_os = "macos"
        ))]
        {
            if self.is_aio() {
                if one {
                    write!(fmt, " | ")?
                }
                write!(fmt, "AIO")?;
                one = true
            }
        }
        #[cfg(any(target_os = "freebsd"))]
        {
            if self.is_lio() {
                if one {
                    write!(fmt, " | ")?
                }
                write!(fmt, "LIO")?;
                one = true
            }
        }
        debug_assert!(one, "printing empty interests");
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! A collection of serialization and deserialization functions
//! that use the `serde` crate for the serializable and deserializable
//! implementation.

use std::io::{self, Write, Read};
use std::{error, fmt, result};
use std::str::Utf8Error;
use {CountSize, SizeLimit};
use byteorder::ByteOrder;
use std::error::Error as StdError;

pub use super::de::Deserializer;

pub use super::ser::Serializer;

use super::ser::SizeChecker;

use serde_crate as serde;

/// The result of a serialization or deserialization operation.
pub type Result<T> = result::Result<T, Error>;

/// An error that can be produced during (de)serializing.
pub type Error = Box<ErrorKind>;

/// The kind of error that can be produced during a serialization or deserialization.
#[derive(Debug)]
pub enum ErrorKind {
    /// If the error stems from the reader/writer that is being used
    /// during (de)serialization, that error will be stored and returned here.
    Io(io::Error),
    /// Returned if the deserializer attempts to deserialize a string that is not valid utf8
    InvalidUtf8Encoding(Utf8Error),
    /// Returned if the deserializer attempts to deserialize a bool that was
    /// not encoded as either a 1 or a 0
    InvalidBoolEncoding(u8),
    /// Returned if the deserializer attempts to deserialize a char that is not in the correct format.
    InvalidCharEncoding,
    /// Returned if the deserializer attempts to deserialize the tag of an enum that is
    /// not in the expected ranges
    InvalidTagEncoding(usize),
    /// Serde has a deserialize_any method that lets the format hint to the
    /// object which route to take in deserializing.
    DeserializeAnyNotSupported,
    /// If (de)serializing a message takes more than the provided size limit, this
    /// error is returned.
    SizeLimit,
    /// Bincode can not encode sequences of unknown length (like iterators).
    SequenceMustHaveLength,
    /// A custom error message from Serde.
    Custom(String),
}

impl StdError for ErrorKind {
    fn description(&self) -> &str {
        match *self {
            ErrorKind::Io(ref err) => error::Error::description(err),
            ErrorKind::InvalidUtf8Encoding(_) => "string is not valid utf8",
            ErrorKind::InvalidBoolEncoding(_) => "invalid u8 while decoding bool",
            ErrorKind::InvalidCharEncoding => "char is not valid",
            ErrorKind::InvalidTagEncoding(_) => "tag for enum is not valid",
            ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences",
            ErrorKind::DeserializeAnyNotSupported => {
                "bincode doesn't support serde::Deserializer::deserialize_any"
            }
            ErrorKind::SizeLimit => "the size limit for decoding has been reached",
            ErrorKind::Custom(ref msg) => msg,

        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::InvalidUtf8Encoding(_) => None,
            ErrorKind::InvalidBoolEncoding(_) => None,
            ErrorKind::InvalidCharEncoding => None,
            ErrorKind::InvalidTagEncoding(_) => None,
            ErrorKind::SequenceMustHaveLength => None,
            ErrorKind::DeserializeAnyNotSupported => None,
            ErrorKind::SizeLimit => None,
            ErrorKind::Custom(_) => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        ErrorKind::Io(err).into()
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ErrorKind::Io(ref ioerr) => write!(fmt, "io error: {}", ioerr),
            ErrorKind::InvalidUtf8Encoding(ref e) => write!(fmt, "{}: {}", self.description(), e),
            ErrorKind::InvalidBoolEncoding(b) => {
                write!(fmt, "{}, expected 0 or 1, found {}", self.description(), b)
            }
            ErrorKind::InvalidCharEncoding => write!(fmt, "{}", self.description()),
            ErrorKind::InvalidTagEncoding(tag) => {
                write!(fmt, "{}, found {}", self.description(), tag)
            }
            ErrorKind::SequenceMustHaveLength => {
                write!(
                    fmt,
                    "bincode can only encode sequences and maps that have a knowable size ahead of time."
                )
            }
            ErrorKind::SizeLimit => write!(fmt, "size limit was exceeded"),
            ErrorKind::DeserializeAnyNotSupported => {
                write!(
                    fmt,
                    "bincode does not support the serde::Deserializer::deserialize_any method"
                )
            }
            ErrorKind::Custom(ref s) => s.fmt(fmt),
        }
    }
}

impl serde::de::Error for Error {
    fn custom<T: fmt::Display>(desc: T) -> Error {
        ErrorKind::Custom(desc.to_string()).into()
    }
}

impl serde::ser::Error for Error {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        ErrorKind::Custom(msg.to_string()).into()
    }
}

/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W, T: ?Sized, S, E>(writer: W, value: &T, size_limit: S) -> Result<()>
where
    W: Write,
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    if let Some(limit) = size_limit.limit() {
        try!(serialized_size_bounded(value, limit).ok_or(
            ErrorKind::SizeLimit,
        ));
    }

    let mut serializer = Serializer::<_, E>::new(writer);
    serde::Serialize::serialize(value, &mut serializer)
}

/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S, E>(value: &T, size_limit: S) -> Result<Vec<u8>>
where
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    let mut writer = match size_limit.limit() {
        Some(size_limit) => {
            let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(
                ErrorKind::SizeLimit,
            ));
            Vec::with_capacity(actual_size as usize)
        }
        None => {
            let size = serialized_size(value) as usize;
            Vec::with_capacity(size)
        }
    };

    try!(serialize_into::<_, _, _, E>(
        &mut writer,
        value,
        super::Infinite,
    ));
    Ok(writer)
}

impl SizeLimit for CountSize {
    fn add(&mut self, c: u64) -> Result<()> {
        self.total += c;
        if let Some(limit) = self.limit {
            if self.total > limit {
                return Err(Box::new(ErrorKind::SizeLimit));
            }
        }
        Ok(())
    }

    fn limit(&self) -> Option<u64> {
        unreachable!();
    }
}

/// Returns the size that an object would be if serialized using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn serialized_size<T: ?Sized>(value: &T) -> u64
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: None,
        },
    };

    value.serialize(&mut size_counter).ok();
    size_counter.size_limit.total
}

/// Given a maximum size limit, check how large an object would be if it
/// were to be serialized.
///
/// If it can be serialized in `max` or fewer bytes, that number will be returned
/// inside `Some`.  If it goes over bounds, then None is returned.
pub fn serialized_size_bounded<T: ?Sized>(value: &T, max: u64) -> Option<u64>
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: Some(max),
        },
    };

    match value.serialize(&mut size_counter) {
        Ok(_) => Some(size_counter.size_limit.total),
        Err(_) => None,
    }
}

/// Deserializes an object directly from a `Read`er.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R, T, S, E>(reader: R, size_limit: S) -> Result<T>
where
    R: Read,
    T: serde::de::DeserializeOwned,
    S: SizeLimit,
    E: ByteOrder,
{
    let reader = ::de::read::IoReader::new(reader);
    let mut deserializer = Deserializer::<_, S, E>::new(reader, size_limit);
    serde::Deserialize::deserialize(&mut deserializer)
}

/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T, E: ByteOrder>(bytes: &'a [u8]) -> Result<T>
where
    T: serde::de::Deserialize<'a>,
{
    let reader = ::de::read::SliceReader::new(bytes);
    let mut deserializer = Deserializer::<_, _, E>::new(reader, super::Infinite);
    serde::Deserialize::deserialize(&mut deserializer)
}
<commit_msg>improve size limit error display<commit_after>//! A collection of serialization and deserialization functions
//! that use the `serde` crate for the serializable and deserializable
//! implementation.

use std::io::{self, Write, Read};
use std::{error, fmt, result};
use std::str::Utf8Error;
use {CountSize, SizeLimit};
use byteorder::ByteOrder;
use std::error::Error as StdError;

pub use super::de::Deserializer;

pub use super::ser::Serializer;

use super::ser::SizeChecker;

use serde_crate as serde;

/// The result of a serialization or deserialization operation.
pub type Result<T> = result::Result<T, Error>;

/// An error that can be produced during (de)serializing.
pub type Error = Box<ErrorKind>;

/// The kind of error that can be produced during a serialization or deserialization.
#[derive(Debug)]
pub enum ErrorKind {
    /// If the error stems from the reader/writer that is being used
    /// during (de)serialization, that error will be stored and returned here.
    Io(io::Error),
    /// Returned if the deserializer attempts to deserialize a string that is not valid utf8
    InvalidUtf8Encoding(Utf8Error),
    /// Returned if the deserializer attempts to deserialize a bool that was
    /// not encoded as either a 1 or a 0
    InvalidBoolEncoding(u8),
    /// Returned if the deserializer attempts to deserialize a char that is not in the correct format.
    InvalidCharEncoding,
    /// Returned if the deserializer attempts to deserialize the tag of an enum that is
    /// not in the expected ranges
    InvalidTagEncoding(usize),
    /// Serde has a deserialize_any method that lets the format hint to the
    /// object which route to take in deserializing.
    DeserializeAnyNotSupported,
    /// If (de)serializing a message takes more than the provided size limit, this
    /// error is returned.
    SizeLimit,
    /// Bincode can not encode sequences of unknown length (like iterators).
    SequenceMustHaveLength,
    /// A custom error message from Serde.
    Custom(String),
}

impl StdError for ErrorKind {
    fn description(&self) -> &str {
        match *self {
            ErrorKind::Io(ref err) => error::Error::description(err),
            ErrorKind::InvalidUtf8Encoding(_) => "string is not valid utf8",
            ErrorKind::InvalidBoolEncoding(_) => "invalid u8 while decoding bool",
            ErrorKind::InvalidCharEncoding => "char is not valid",
            ErrorKind::InvalidTagEncoding(_) => "tag for enum is not valid",
            ErrorKind::SequenceMustHaveLength => "bincode can't encode infinite sequences",
            ErrorKind::DeserializeAnyNotSupported => {
                "bincode doesn't support serde::Deserializer::deserialize_any"
            }
            ErrorKind::SizeLimit => "the size limit for decoding has been reached",
            ErrorKind::Custom(ref msg) => msg,

        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::InvalidUtf8Encoding(_) => None,
            ErrorKind::InvalidBoolEncoding(_) => None,
            ErrorKind::InvalidCharEncoding => None,
            ErrorKind::InvalidTagEncoding(_) => None,
            ErrorKind::SequenceMustHaveLength => None,
            ErrorKind::DeserializeAnyNotSupported => None,
            ErrorKind::SizeLimit => None,
            ErrorKind::Custom(_) => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        ErrorKind::Io(err).into()
    }
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ErrorKind::Io(ref ioerr) => write!(fmt, "io error: {}", ioerr),
            ErrorKind::InvalidUtf8Encoding(ref e) => write!(fmt, "{}: {}", self.description(), e),
            ErrorKind::InvalidBoolEncoding(b) => {
                write!(fmt, "{}, expected 0 or 1, found {}", self.description(), b)
            }
            ErrorKind::InvalidCharEncoding => write!(fmt, "{}", self.description()),
            ErrorKind::InvalidTagEncoding(tag) => {
                write!(fmt, "{}, found {}", self.description(), tag)
            }
            ErrorKind::SequenceMustHaveLength => {
                write!(
                    fmt,
                    "bincode can only encode sequences and maps that have a knowable size ahead of time."
                )
            }
            ErrorKind::SizeLimit => write!(fmt, self.description()),
            ErrorKind::DeserializeAnyNotSupported => {
                write!(
                    fmt,
                    "bincode does not support the serde::Deserializer::deserialize_any method"
                )
            }
            ErrorKind::Custom(ref s) => s.fmt(fmt),
        }
    }
}

impl serde::de::Error for Error {
    fn custom<T: fmt::Display>(desc: T) -> Error {
        ErrorKind::Custom(desc.to_string()).into()
    }
}

impl serde::ser::Error for Error {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        ErrorKind::Custom(msg.to_string()).into()
    }
}

/// Serializes an object directly into a `Writer`.
///
/// If the serialization would take more bytes than allowed by `size_limit`, an error
/// is returned and *no bytes* will be written into the `Writer`.
///
/// If this returns an `Error` (other than SizeLimit), assume that the
/// writer is in an invalid state, as writing could bail out in the middle of
/// serializing.
pub fn serialize_into<W, T: ?Sized, S, E>(writer: W, value: &T, size_limit: S) -> Result<()>
where
    W: Write,
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    if let Some(limit) = size_limit.limit() {
        try!(serialized_size_bounded(value, limit).ok_or(
            ErrorKind::SizeLimit,
        ));
    }

    let mut serializer = Serializer::<_, E>::new(writer);
    serde::Serialize::serialize(value, &mut serializer)
}

/// Serializes a serializable object into a `Vec` of bytes.
///
/// If the serialization would take more bytes than allowed by `size_limit`,
/// an error is returned.
pub fn serialize<T: ?Sized, S, E>(value: &T, size_limit: S) -> Result<Vec<u8>>
where
    T: serde::Serialize,
    S: SizeLimit,
    E: ByteOrder,
{
    let mut writer = match size_limit.limit() {
        Some(size_limit) => {
            let actual_size = try!(serialized_size_bounded(value, size_limit).ok_or(
                ErrorKind::SizeLimit,
            ));
            Vec::with_capacity(actual_size as usize)
        }
        None => {
            let size = serialized_size(value) as usize;
            Vec::with_capacity(size)
        }
    };

    try!(serialize_into::<_, _, _, E>(
        &mut writer,
        value,
        super::Infinite,
    ));
    Ok(writer)
}

impl SizeLimit for CountSize {
    fn add(&mut self, c: u64) -> Result<()> {
        self.total += c;
        if let Some(limit) = self.limit {
            if self.total > limit {
                return Err(Box::new(ErrorKind::SizeLimit));
            }
        }
        Ok(())
    }

    fn limit(&self) -> Option<u64> {
        unreachable!();
    }
}

/// Returns the size that an object would be if serialized using bincode.
///
/// This is used internally as part of the check for encode_into, but it can
/// be useful for preallocating buffers if thats your style.
pub fn serialized_size<T: ?Sized>(value: &T) -> u64
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: None,
        },
    };

    value.serialize(&mut size_counter).ok();
    size_counter.size_limit.total
}

/// Given a maximum size limit, check how large an object would be if it
/// were to be serialized.
///
/// If it can be serialized in `max` or fewer bytes, that number will be returned
/// inside `Some`.  If it goes over bounds, then None is returned.
pub fn serialized_size_bounded<T: ?Sized>(value: &T, max: u64) -> Option<u64>
where
    T: serde::Serialize,
{
    let mut size_counter = SizeChecker {
        size_limit: CountSize {
            total: 0,
            limit: Some(max),
        },
    };

    match value.serialize(&mut size_counter) {
        Ok(_) => Some(size_counter.size_limit.total),
        Err(_) => None,
    }
}

/// Deserializes an object directly from a `Read`er.
///
/// If the provided `SizeLimit` is reached, the deserialization will bail immediately.
/// A SizeLimit can help prevent an attacker from flooding your server with
/// a neverending stream of values that runs your server out of memory.
///
/// If this returns an `Error`, assume that the buffer that you passed
/// in is in an invalid state, as the error could be returned during any point
/// in the reading.
pub fn deserialize_from<R, T, S, E>(reader: R, size_limit: S) -> Result<T>
where
    R: Read,
    T: serde::de::DeserializeOwned,
    S: SizeLimit,
    E: ByteOrder,
{
    let reader = ::de::read::IoReader::new(reader);
    let mut deserializer = Deserializer::<_, S, E>::new(reader, size_limit);
    serde::Deserialize::deserialize(&mut deserializer)
}

/// Deserializes a slice of bytes into an object.
///
/// This method does not have a size-limit because if you already have the bytes
/// in memory, then you don't gain anything by having a limiter.
pub fn deserialize<'a, T, E: ByteOrder>(bytes: &'a [u8]) -> Result<T>
where
    T: serde::de::Deserialize<'a>,
{
    let reader = ::de::read::SliceReader::new(bytes);
    let mut deserializer = Deserializer::<_, _, E>::new(reader, super::Infinite);
    serde::Deserialize::deserialize(&mut deserializer)
}
<|endoftext|>