<commit_before>//! Rotates & Shifts
use jeebie::core::cpu::CPU;
use jeebie::core::registers::Register8::*;
use jeebie::core::registers::Register16::*;

// 'RLCA' 07 4
pub fn RLCA(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(A);
    4
}

// 'RLA' 17 4
pub fn RLA(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(A);
    4
}

// 'RRCA' 0F 4
pub fn RRCA(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(A);
    4
}

// 'RRA' 1F 4
pub fn RRA(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(A);
    4
}

// 'RLC A' CB 07 8
pub fn RLC_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(A);
    8
}

// 'RLC B' CB 00 8
pub fn RLC_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(B);
    8
}

// 'RLC C' CB 01 8
pub fn RLC_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(C);
    8
}

// 'RLC D' CB 02 8
pub fn RLC_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(D);
    8
}

// 'RLC E' CB 03 8
pub fn RLC_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(E);
    8
}

// 'RLC H' CB 04 8
pub fn RLC_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(H);
    8
}

// 'RLC L' CB 05 8
pub fn RLC_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(L);
    8
}

// 'RLC (HL)' CB 06 16
pub fn RLC_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(RegisterAddress(HL));
    16
}

// 'RL A' CB 17 8
pub fn RL_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(A);
    8
}

// 'RL B' CB 10 8
pub fn RL_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(B);
    8
}

// 'RL C' CB 11 8
pub fn RL_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(C);
    8
}

// 'RL D' CB 12 8
pub fn RL_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(D);
    8
}

// 'RL E' CB 13 8
pub fn RL_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(E);
    8
}

// 'RL H' CB 14 8
pub fn RL_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(H);
    8
}

// 'RL L' CB 15 8
pub fn RL_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(L);
    8
}

// 'RL (HL)' CB 16 16
pub fn RL_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(RegisterAddress(HL));
    16
}

// 'RRC A' CB 0F 8
pub fn RRC_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(A);
    8
}

// 'RRC B' CB 08 8
pub fn RRC_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(B);
    8
}

// 'RRC C' CB 09 8
pub fn RRC_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(C);
    8
}

// 'RRC D' CB 0A 8
pub fn RRC_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(D);
    8
}

// 'RRC E' CB 0B 8
pub fn RRC_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(E);
    8
}

// 'RRC H' CB 0C 8
pub fn RRC_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(H);
    8
}

// 'RRC L' CB 0D 8
pub fn RRC_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(L);
    8
}

// 'RRC (HL)' CB 0E 16
pub fn RRC_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(RegisterAddress(HL));
    16
}

// 'RR A' CB 1F 8
pub fn RR_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(A);
    8
}

// 'RR B' CB 18 8
pub fn RR_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(B);
    8
}

// 'RR C' CB 19 8
pub fn RR_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(C);
    8
}

// 'RR D' CB 1A 8
pub fn RR_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(D);
    8
}

// 'RR E' CB 1B 8
pub fn RR_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(E);
    8
}

// 'RR H' CB 1C 8
pub fn RR_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(H);
    8
}

// 'RR L' CB 1D 8
pub fn RR_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(L);
    8
}

// 'RR (HL)' CB 1E 16
pub fn RR_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(RegisterAddress(HL));
    16
}<commit_msg>Added SLA instructions<commit_after>//! Rotates & Shifts
use jeebie::core::cpu::CPU;
use jeebie::core::registers::Register8::*;
use jeebie::core::registers::Register16::*;

// 'RLCA' 07 4
pub fn RLCA(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(A);
    4
}

// 'RLA' 17 4
pub fn RLA(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(A);
    4
}

// 'RRCA' 0F 4
pub fn RRCA(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(A);
    4
}

// 'RRA' 1F 4
pub fn RRA(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(A);
    4
}

// 'RLC A' CB 07 8
pub fn RLC_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(A);
    8
}

// 'RLC B' CB 00 8
pub fn RLC_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(B);
    8
}

// 'RLC C' CB 01 8
pub fn RLC_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(C);
    8
}

// 'RLC D' CB 02 8
pub fn RLC_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(D);
    8
}

// 'RLC E' CB 03 8
pub fn RLC_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(E);
    8
}

// 'RLC H' CB 04 8
pub fn RLC_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(H);
    8
}

// 'RLC L' CB 05 8
pub fn RLC_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(L);
    8
}

// 'RLC (HL)' CB 06 16
pub fn RLC_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_left_carry(RegisterAddress(HL));
    16
}

// 'RL A' CB 17 8
pub fn RL_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(A);
    8
}

// 'RL B' CB 10 8
pub fn RL_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(B);
    8
}

// 'RL C' CB 11 8
pub fn RL_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(C);
    8
}

// 'RL D' CB 12 8
pub fn RL_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(D);
    8
}

// 'RL E' CB 13 8
pub fn RL_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(E);
    8
}

// 'RL H' CB 14 8
pub fn RL_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(H);
    8
}

// 'RL L' CB 15 8
pub fn RL_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(L);
    8
}

// 'RL (HL)' CB 16 16
pub fn RL_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_left(RegisterAddress(HL));
    16
}

// 'RRC A' CB 0F 8
pub fn RRC_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(A);
    8
}

// 'RRC B' CB 08 8
pub fn RRC_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(B);
    8
}

// 'RRC C' CB 09 8
pub fn RRC_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(C);
    8
}

// 'RRC D' CB 0A 8
pub fn RRC_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(D);
    8
}

// 'RRC E' CB 0B 8
pub fn RRC_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(E);
    8
}

// 'RRC H' CB 0C 8
pub fn RRC_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(H);
    8
}

// 'RRC L' CB 0D 8
pub fn RRC_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(L);
    8
}

// 'RRC (HL)' CB 0E 16
pub fn RRC_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_right_carry(RegisterAddress(HL));
    16
}

// 'RR A' CB 1F 8
pub fn RR_A(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(A);
    8
}

// 'RR B' CB 18 8
pub fn RR_B(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(B);
    8
}

// 'RR C' CB 19 8
pub fn RR_C(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(C);
    8
}

// 'RR D' CB 1A 8
pub fn RR_D(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(D);
    8
}

// 'RR E' CB 1B 8
pub fn RR_E(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(E);
    8
}

// 'RR H' CB 1C 8
pub fn RR_H(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(H);
    8
}

// 'RR L' CB 1D 8
pub fn RR_L(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(L);
    8
}

// 'RR (HL)' CB 1E 16
pub fn RR_HLm(cpu: &mut CPU) -> i32 {
    cpu.rotate_right(RegisterAddress(HL));
    16
}

 // 'SLA A' CB 27 8
 pub fn SLA_A(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, A);
     8
 }

 // 'SLA B' CB 20 8
 pub fn SLA_B(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, B);
     8
 }

 // 'SLA C' CB 21 8
 pub fn SLA_C(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, C);
     8
 }

 // 'SLA D' CB 22 8
 pub fn SLA_D(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, D);
     8
 }

 // 'SLA E' CB 23 8
 pub fn SLA_E(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, E);
     8
 }

 // 'SLA H' CB 24 8
 pub fn SLA_H(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, H);
     8
 }

 // 'SLA L' CB 25 8
 pub fn SLA_L(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, L);
     8
 }

 // 'SLA (HL)' CB 26 16
 pub fn SLA_HLm(cpu: &mut CPU) -> i32 {
     cpu.compute_shift(true, RegisterAddress(HL));
     16
 }
<|endoftext|>


<commit_before>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use std::error;
use std::result;
use std::fmt;
use std::borrow::Cow;

#[derive(Debug, PartialEq, Clone)]
/// Source of an error file
pub struct Source {
    /// File name of the source
    pub file: Option<String>,
    /// Line number of the source
    pub line: Option<u32>,
}

impl Source {
    /// Create an empty source, with both fields set to None
    pub fn empty() -> Source {
        Source { file: None, line: None }
    }

    /// Create a new source pointing to file
    pub fn new<S: Into<String>>(s: S) -> Source {
        Source { file: Some(s.into()), line: None }
    }

    /// Sets line number of a source
    pub fn line(mut self, line: u32) -> Source {
        self.line = Some(line);
        self
    }

    /// Sets line number of a source (with &mut self)
    pub fn set_line(&mut self, line: u32) {
        self.line = Some(line);
    }

    /// Unsets a line number of a source
    pub fn unset_line(&mut self) {
        self.line = None;
    }
}

impl<'a> From<&'a Source> for Source {
    fn from(s: &'a Source) -> Source {
        s.clone()
    }
}
#[derive(Debug, PartialEq)]
/// Crowbook Error type
pub struct Error {
    /// Origin (file, line) of the error, if there is one
    source: Source,
    inner: Inner,
}

impl Error {
    /// Creates a new default error
    pub fn default<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Default(msg.into())
        }
    }

    /// Creates a new parser error
    ///
    /// Error when parsing markdown file
    pub fn parser<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Parser(msg.into())
        }
    }

    /// Creates a new config parser error
    ///
    /// Error when parsing book file
    pub fn config_parser<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::ConfigParser(msg.into())
        }
    }

    /// Creates a new file not found error
    ///
    /// * msg: description of why the file was needed
    /// * file: file name
    pub fn file_not_found<S1: Into<Cow<'static, str>>, S2: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S1, file: S2) -> Error {
        Error {
            source: source.into(),
            inner: Inner::FileNotFound(msg.into(), file.into())
        }
    }

    /// Creates a new render error
    ///
    /// Error when rendering
    pub fn render<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Render(msg.into())
        }
    }

    /// Creates a new invalid option error
    ///
    /// Error when trying to set an option
    pub fn invalid_option<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::InvalidOption(msg.into())
        }
    }

    /// Creates a new zipper error
    ///
    /// Error when moving/copying files to temporary dir, e.g. using `zip` commmand
    pub fn zipper<S: Into<Cow<'static, str>>>(msg: S) -> Error {
        Error {
            source: Source::empty(),
            inner: Inner::Zipper(msg.into())
        }
    }

    /// Creates a new book option error
    ///
    /// Used when converting an error to invalid type
    pub fn book_option<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::BookOption(msg.into())
        }
    }

    /// Change the source of an error
    pub fn with_source<O: Into<Source>>(mut self, source: O) -> Error {
        self.source = source.into();
        self
    }

    /// Returns true if error is a book option error
    pub fn is_book_option(&self) -> bool {
        match self.inner {
            Inner::BookOption(..) => true,
            _ => false,
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self.inner {
            Inner::Default(ref s)
                | Inner::Parser(ref s)
                | Inner::Zipper(ref s)
                | Inner::BookOption(ref s)
                | Inner::ConfigParser(ref s)
                | Inner::InvalidOption(ref s)
                | Inner::Render(ref s)
                => s.as_ref(),

            Inner::FileNotFound(..) => "File not found",
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let source = &self.source;
        if let Some(ref file) = source.file {
            try!(write!(f, "Error in file {}", file));
            if let Some(line) = source.line {
                try!(write!(f, " line {}\n", line));
            }
        }

        match self.inner {
            Inner::Default(ref s) => {
                write!(f, "Error: {}", s)
            },
            Inner::Parser(ref s) => {
                write!(f, "Error parsing markdown: {}", s)
            },
            Inner::ConfigParser(ref s) => {
                try!(f.write_str("Error parsing configuration file: "));
                f.write_str(s)
            },
            Inner::FileNotFound(ref description, ref file) => {
                try!(write!(f, "File not found ({}):", description));
                f.write_str(file)
            },
            Inner::Render(ref s) => {
                try!(f.write_str("Error during rendering: "));
                f.write_str(s)
            },
            Inner::Zipper(ref s) => {
                try!(f.write_str("Error during temporary files editing: "));
                f.write_str(s)
            },
            Inner::BookOption(ref s) => {
                try!(f.write_str("Error converting BookOption: "));
                f.write_str(s)
            },
            Inner::InvalidOption(ref s) => {
                try!(f.write_str("Error accessing book option: "));
                f.write_str(s)
            },
        }
    }
}

/// Crowbook's Result type, used by many methods that can fail
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug, PartialEq)]
enum Inner {
    /// Default variant
    Default(Cow<'static, str>),
    /// An error in Parsing markdown file
    Parser(Cow<'static, str>),
    /// An error in parsing a book configuration file
    ConfigParser(Cow<'static, str>),
    /// An error when a file is not found
    FileNotFound(Cow<'static, str>, Cow<'static, str>), //description, file
    /// An error in a renderer
    Render(Cow<'static, str>),
    /// An error during "zipping" processus
    Zipper(Cow<'static, str>),
    /// An error relative to BookOption convertion (usually a type error)
    BookOption(Cow<'static, str>),
    /// An invalid option
    InvalidOption(Cow<'static, str>),
}
<commit_msg>Remove source::file method as it isn't used<commit_after>// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use std::error;
use std::result;
use std::fmt;
use std::borrow::Cow;

#[derive(Debug, PartialEq, Clone)]
/// Source of an error file
pub struct Source {
    /// File name of the source
    pub file: Option<String>,
    /// Line number of the source
    pub line: Option<u32>,
}

impl Source {
    /// Create an empty source, with both fields set to None
    pub fn empty() -> Source {
        Source { file: None, line: None }
    }

    /// Create a new source pointing to file
    pub fn new<S: Into<String>>(s: S) -> Source {
        Source { file: Some(s.into()), line: None }
    }

    /// Sets line number of a source (with &mut self)
    pub fn set_line(&mut self, line: u32) {
        self.line = Some(line);
    }

    /// Unsets a line number of a source
    pub fn unset_line(&mut self) {
        self.line = None;
    }
}

impl<'a> From<&'a Source> for Source {
    fn from(s: &'a Source) -> Source {
        s.clone()
    }
}
#[derive(Debug, PartialEq)]
/// Crowbook Error type
pub struct Error {
    /// Origin (file, line) of the error, if there is one
    source: Source,
    inner: Inner,
}

impl Error {
    /// Creates a new default error
    pub fn default<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Default(msg.into())
        }
    }

    /// Creates a new parser error
    ///
    /// Error when parsing markdown file
    pub fn parser<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Parser(msg.into())
        }
    }

    /// Creates a new config parser error
    ///
    /// Error when parsing book file
    pub fn config_parser<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::ConfigParser(msg.into())
        }
    }

    /// Creates a new file not found error
    ///
    /// * msg: description of why the file was needed
    /// * file: file name
    pub fn file_not_found<S1: Into<Cow<'static, str>>, S2: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S1, file: S2) -> Error {
        Error {
            source: source.into(),
            inner: Inner::FileNotFound(msg.into(), file.into())
        }
    }

    /// Creates a new render error
    ///
    /// Error when rendering
    pub fn render<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::Render(msg.into())
        }
    }

    /// Creates a new invalid option error
    ///
    /// Error when trying to set an option
    pub fn invalid_option<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::InvalidOption(msg.into())
        }
    }

    /// Creates a new zipper error
    ///
    /// Error when moving/copying files to temporary dir, e.g. using `zip` commmand
    pub fn zipper<S: Into<Cow<'static, str>>>(msg: S) -> Error {
        Error {
            source: Source::empty(),
            inner: Inner::Zipper(msg.into())
        }
    }

    /// Creates a new book option error
    ///
    /// Used when converting an error to invalid type
    pub fn book_option<S: Into<Cow<'static, str>>, O: Into<Source>>(source: O, msg: S) -> Error {
        Error {
            source: source.into(),
            inner: Inner::BookOption(msg.into())
        }
    }

    /// Change the source of an error
    pub fn with_source<O: Into<Source>>(mut self, source: O) -> Error {
        self.source = source.into();
        self
    }

    /// Returns true if error is a book option error
    pub fn is_book_option(&self) -> bool {
        match self.inner {
            Inner::BookOption(..) => true,
            _ => false,
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self.inner {
            Inner::Default(ref s)
                | Inner::Parser(ref s)
                | Inner::Zipper(ref s)
                | Inner::BookOption(ref s)
                | Inner::ConfigParser(ref s)
                | Inner::InvalidOption(ref s)
                | Inner::Render(ref s)
                => s.as_ref(),

            Inner::FileNotFound(..) => "File not found",
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let source = &self.source;
        if let Some(ref file) = source.file {
            try!(write!(f, "Error in file {}", file));
            if let Some(line) = source.line {
                try!(write!(f, " line {}\n", line));
            }
        }

        match self.inner {
            Inner::Default(ref s) => {
                write!(f, "Error: {}", s)
            },
            Inner::Parser(ref s) => {
                write!(f, "Error parsing markdown: {}", s)
            },
            Inner::ConfigParser(ref s) => {
                try!(f.write_str("Error parsing configuration file: "));
                f.write_str(s)
            },
            Inner::FileNotFound(ref description, ref file) => {
                try!(write!(f, "File not found ({}):", description));
                f.write_str(file)
            },
            Inner::Render(ref s) => {
                try!(f.write_str("Error during rendering: "));
                f.write_str(s)
            },
            Inner::Zipper(ref s) => {
                try!(f.write_str("Error during temporary files editing: "));
                f.write_str(s)
            },
            Inner::BookOption(ref s) => {
                try!(f.write_str("Error converting BookOption: "));
                f.write_str(s)
            },
            Inner::InvalidOption(ref s) => {
                try!(f.write_str("Error accessing book option: "));
                f.write_str(s)
            },
        }
    }
}

/// Crowbook's Result type, used by many methods that can fail
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug, PartialEq)]
enum Inner {
    /// Default variant
    Default(Cow<'static, str>),
    /// An error in Parsing markdown file
    Parser(Cow<'static, str>),
    /// An error in parsing a book configuration file
    ConfigParser(Cow<'static, str>),
    /// An error when a file is not found
    FileNotFound(Cow<'static, str>, Cow<'static, str>), //description, file
    /// An error in a renderer
    Render(Cow<'static, str>),
    /// An error during "zipping" processus
    Zipper(Cow<'static, str>),
    /// An error relative to BookOption convertion (usually a type error)
    BookOption(Cow<'static, str>),
    /// An invalid option
    InvalidOption(Cow<'static, str>),
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests;

use crate::cmp;
use crate::fmt;
use crate::io::{
    self, BufRead, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
};
use crate::mem;

// =============================================================================
// Forwarding implementations

#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for &mut R {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        (**self).read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        (**self).is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        (**self).initializer()
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_to_end(buf)
    }

    #[inline]
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_to_string(buf)
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        (**self).read_exact(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for &mut W {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        (**self).write_vectored(bufs)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        (**self).is_write_vectored()
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        (**self).write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        (**self).write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for &mut S {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for &mut B {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }

    #[inline]
    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_until(byte, buf)
    }

    #[inline]
    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_line(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        (**self).read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        (**self).is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        (**self).initializer()
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_to_end(buf)
    }

    #[inline]
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_to_string(buf)
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        (**self).read_exact(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for Box<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        (**self).write_vectored(bufs)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        (**self).is_write_vectored()
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        (**self).write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        (**self).write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for Box<S> {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }

    #[inline]
    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_until(byte, buf)
    }

    #[inline]
    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_line(buf)
    }
}

// =============================================================================
// In-memory buffer implementations

/// Read is implemented for `&[u8]` by copying from the slice.
///
/// Note that reading updates the slice to point to the yet unread part.
/// The slice will be empty when EOF is reached.
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for &[u8] {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = cmp::min(buf.len(), self.len());
        let (a, b) = self.split_at(amt);

        // First check if the amount of bytes we want to read is small:
        // `copy_from_slice` will generally expand to a call to `memcpy`, and
        // for a single byte the overhead is significant.
        if amt == 1 {
            buf[0] = a[0];
        } else {
            buf[..amt].copy_from_slice(a);
        }

        *self = b;
        Ok(amt)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        let mut nread = 0;
        for buf in bufs {
            nread += self.read(buf)?;
            if self.is_empty() {
                break;
            }
        }

        Ok(nread)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        true
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        Initializer::nop()
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        if buf.len() > self.len() {
            return Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"));
        }
        let (a, b) = self.split_at(buf.len());

        // First check if the amount of bytes we want to read is small:
        // `copy_from_slice` will generally expand to a call to `memcpy`, and
        // for a single byte the overhead is significant.
        if buf.len() == 1 {
            buf[0] = a[0];
        } else {
            buf.copy_from_slice(a);
        }

        *self = b;
        Ok(())
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        buf.extend_from_slice(*self);
        let len = self.len();
        *self = &self[len..];
        Ok(len)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for &[u8] {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        Ok(*self)
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        *self = &self[amt..];
    }
}

/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
/// its data.
///
/// Note that writing updates the slice to point to the yet unwritten part.
/// The slice will be empty when it has been completely overwritten.
///
/// If the number of bytes to be written exceeds the size of the slice, write operations will
/// return short writes: ultimately, `Ok(0)`; in this situation, `write_all` returns an error of
/// kind `ErrorKind::WriteZero`.
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for &mut [u8] {
    #[inline]
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let amt = cmp::min(data.len(), self.len());
        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
        a.copy_from_slice(&data[..amt]);
        *self = b;
        Ok(amt)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        let mut nwritten = 0;
        for buf in bufs {
            nwritten += self.write(buf)?;
            if self.is_empty() {
                break;
            }
        }

        Ok(nwritten)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    #[inline]
    fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
        if self.write(data)? == data.len() {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
        }
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

/// Write is implemented for `Vec<u8>` by appending to the vector.
/// The vector will grow as needed.
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Vec<u8> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.extend_from_slice(buf);
        Ok(buf.len())
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        let len = bufs.iter().map(|b| b.len()).sum();
        self.reserve(len);
        for buf in bufs {
            self.extend_from_slice(buf);
        }
        Ok(len)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.extend_from_slice(buf);
        Ok(())
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}
<commit_msg>Rollup merge of #82862 - athre0z:generalize-vec-write-impl, r=TimDiekmann<commit_after>#[cfg(test)]
mod tests;

use crate::alloc::Allocator;
use crate::cmp;
use crate::fmt;
use crate::io::{
    self, BufRead, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
};
use crate::mem;

// =============================================================================
// Forwarding implementations

#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for &mut R {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        (**self).read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        (**self).is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        (**self).initializer()
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_to_end(buf)
    }

    #[inline]
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_to_string(buf)
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        (**self).read_exact(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for &mut W {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        (**self).write_vectored(bufs)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        (**self).is_write_vectored()
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        (**self).write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        (**self).write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for &mut S {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for &mut B {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }

    #[inline]
    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_until(byte, buf)
    }

    #[inline]
    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_line(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        (**self).read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        (**self).is_read_vectored()
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        (**self).initializer()
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_to_end(buf)
    }

    #[inline]
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_to_string(buf)
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        (**self).read_exact(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for Box<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        (**self).write_vectored(bufs)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        (**self).is_write_vectored()
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        (**self).write_all(buf)
    }

    #[inline]
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        (**self).write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for Box<S> {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }

    #[inline]
    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
        (**self).read_until(byte, buf)
    }

    #[inline]
    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        (**self).read_line(buf)
    }
}

// =============================================================================
// In-memory buffer implementations

/// Read is implemented for `&[u8]` by copying from the slice.
///
/// Note that reading updates the slice to point to the yet unread part.
/// The slice will be empty when EOF is reached.
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for &[u8] {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = cmp::min(buf.len(), self.len());
        let (a, b) = self.split_at(amt);

        // First check if the amount of bytes we want to read is small:
        // `copy_from_slice` will generally expand to a call to `memcpy`, and
        // for a single byte the overhead is significant.
        if amt == 1 {
            buf[0] = a[0];
        } else {
            buf[..amt].copy_from_slice(a);
        }

        *self = b;
        Ok(amt)
    }

    #[inline]
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        let mut nread = 0;
        for buf in bufs {
            nread += self.read(buf)?;
            if self.is_empty() {
                break;
            }
        }

        Ok(nread)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        true
    }

    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        Initializer::nop()
    }

    #[inline]
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        if buf.len() > self.len() {
            return Err(Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"));
        }
        let (a, b) = self.split_at(buf.len());

        // First check if the amount of bytes we want to read is small:
        // `copy_from_slice` will generally expand to a call to `memcpy`, and
        // for a single byte the overhead is significant.
        if buf.len() == 1 {
            buf[0] = a[0];
        } else {
            buf.copy_from_slice(a);
        }

        *self = b;
        Ok(())
    }

    #[inline]
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        buf.extend_from_slice(*self);
        let len = self.len();
        *self = &self[len..];
        Ok(len)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for &[u8] {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        Ok(*self)
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        *self = &self[amt..];
    }
}

/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
/// its data.
///
/// Note that writing updates the slice to point to the yet unwritten part.
/// The slice will be empty when it has been completely overwritten.
///
/// If the number of bytes to be written exceeds the size of the slice, write operations will
/// return short writes: ultimately, `Ok(0)`; in this situation, `write_all` returns an error of
/// kind `ErrorKind::WriteZero`.
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for &mut [u8] {
    #[inline]
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let amt = cmp::min(data.len(), self.len());
        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
        a.copy_from_slice(&data[..amt]);
        *self = b;
        Ok(amt)
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        let mut nwritten = 0;
        for buf in bufs {
            nwritten += self.write(buf)?;
            if self.is_empty() {
                break;
            }
        }

        Ok(nwritten)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    #[inline]
    fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
        if self.write(data)? == data.len() {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
        }
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

/// Write is implemented for `Vec<u8>` by appending to the vector.
/// The vector will grow as needed.
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Allocator> Write for Vec<u8, A> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.extend_from_slice(buf);
        Ok(buf.len())
    }

    #[inline]
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        let len = bufs.iter().map(|b| b.len()).sum();
        self.reserve(len);
        for buf in bufs {
            self.extend_from_slice(buf);
        }
        Ok(len)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.extend_from_slice(buf);
        Ok(())
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
//
// 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.

use glib;
use glib::subclass;
use glib::subclass::prelude::*;
use gst;
use gst::subclass::prelude::*;
use gst::SECOND_VAL;
use gst_base::prelude::*;
use gst_base::subclass::prelude::*;
use gstreamer::format::Bytes;
use gstreamer_base as gst_base;

use crate::constants::{
    CDG_COMMAND, CDG_HEIGHT, CDG_MASK, CDG_PACKET_PERIOD, CDG_PACKET_SIZE, CDG_WIDTH,
};

const CDG_CMD_MEMORY_PRESET: u8 = 1;

struct CdgParse {
    cat: gst::DebugCategory,
}

impl ObjectSubclass for CdgParse {
    const NAME: &'static str = "CdgParse";
    type ParentType = gst_base::BaseParse;
    type Instance = gst::subclass::ElementInstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            cat: gst::DebugCategory::new(
                "cdgparse",
                gst::DebugColorFlags::empty(),
                Some("CDG parser"),
            ),
        }
    }

    fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
        klass.set_metadata(
            "CDG parser",
            "Codec/Parser/Video",
            "CDG parser",
            "Guillaume Desmottes <guillaume.desmottes@collabora.com>",
        );

        let sink_caps = gst::Caps::new_simple("video/x-cdg", &[]);
        let sink_pad_template = gst::PadTemplate::new(
            "sink",
            gst::PadDirection::Sink,
            gst::PadPresence::Always,
            &sink_caps,
        )
        .unwrap();
        klass.add_pad_template(sink_pad_template);

        let src_caps = gst::Caps::new_simple(
            "video/x-cdg",
            &[
                ("width", &(CDG_WIDTH as i32)),
                ("height", &(CDG_HEIGHT as i32)),
                ("framerate", &gst::Fraction::new(0, 1)),
                ("parsed", &true),
            ],
        );
        let src_pad_template = gst::PadTemplate::new(
            "src",
            gst::PadDirection::Src,
            gst::PadPresence::Always,
            &src_caps,
        )
        .unwrap();
        klass.add_pad_template(src_pad_template);
    }
}

impl ObjectImpl for CdgParse {
    glib_object_impl!();
}

impl ElementImpl for CdgParse {}

fn bytes_to_time(bytes: u64) -> gst::ClockTime {
    let nb = bytes / CDG_PACKET_SIZE as u64;
    let ns = nb.mul_div_round(SECOND_VAL, CDG_PACKET_PERIOD).unwrap();

    gst::ClockTime::from_nseconds(ns)
}

fn time_to_bytes(time: gst::ClockTime) -> Option<Bytes> {
    match time.nseconds() {
        Some(time) => {
            let bytes = time.mul_div_round(CDG_PACKET_PERIOD * CDG_PACKET_SIZE as u64, SECOND_VAL);
            Some(Bytes(bytes))
        }
        None => None,
    }
}

impl BaseParseImpl for CdgParse {
    fn start(&self, element: &gst_base::BaseParse) -> Result<(), gst::ErrorMessage> {
        element.set_min_frame_size(CDG_PACKET_SIZE as u32);

        /* Set duration */
        let mut query = gst::Query::new_duration(gst::Format::Bytes);
        let pad = element.get_src_pad();
        if pad.query(&mut query) {
            let size = query.get_result().get_value() as u64;
            let duration = bytes_to_time(size);
            element.set_duration(duration, 0);
        }

        Ok(())
    }

    fn handle_frame(
        &self,
        element: &gst_base::BaseParse,
        frame: gst_base::BaseParseFrame,
    ) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
        let pad = element.get_src_pad();
        if pad.get_current_caps().is_none() {
            // Set src pad caps
            let src_caps = gst::Caps::new_simple(
                "video/x-cdg",
                &[
                    ("width", &(CDG_WIDTH as i32)),
                    ("height", &(CDG_HEIGHT as i32)),
                    ("framerate", &gst::Fraction::new(0, 1)),
                    ("parsed", &true),
                ],
            );

            pad.push_event(gst::Event::new_caps(&src_caps).build());
        }

        // Scan for CDG instruction
        let input = frame.get_buffer().unwrap();
        let skip = {
            let map = input.map_readable().ok_or_else(|| {
                gst_element_error!(
                    element,
                    gst::CoreError::Failed,
                    ["Failed to map input buffer readable"]
                );
                gst::FlowError::Error
            })?;
            let data = map.as_slice();

            data.iter()
                .enumerate()
                .find(|(_, byte)| (*byte & CDG_MASK == CDG_COMMAND))
                .map(|(i, _)| i)
                .unwrap_or(input.get_size()) // skip the whole buffer
                as u32
        };

        if skip != 0 {
            // Skip to the start of the CDG packet
            return Ok((gst::FlowSuccess::Ok, skip));
        }

        let keyframe = {
            let map = input.map_readable().ok_or_else(|| {
                gst_element_error!(
                    element,
                    gst::CoreError::Failed,
                    ["Failed to map input buffer readable"]
                );
                gst::FlowError::Error
            })?;
            let data = map.as_slice();

            // consider memory preset as keyframe as it clears the screen
            data[1] & CDG_MASK == CDG_CMD_MEMORY_PRESET
        };

        let pts = bytes_to_time(frame.get_offset() as u64);
        let buffer = frame.get_buffer().unwrap();
        buffer.set_pts(pts);

        if !keyframe {
            buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
        }

        gst_debug!(self.cat, obj: element, "Found frame pts={}", pts);

        element.finish_frame(frame, CDG_PACKET_SIZE as u32)?;

        Ok((gst::FlowSuccess::Ok, skip))
    }

    fn convert<V: Into<gst::GenericFormattedValue>>(
        &self,
        _element: &gst_base::BaseParse,
        src_val: V,
        dest_format: gst::Format,
    ) -> Option<gst::GenericFormattedValue> {
        let src_val = src_val.into();

        match (src_val, dest_format) {
            (gst::GenericFormattedValue::Bytes(bytes), gst::Format::Time) => Some(
                gst::GenericFormattedValue::Time(bytes_to_time(bytes.unwrap())),
            ),
            (gst::GenericFormattedValue::Time(time), gst::Format::Bytes) => {
                match time_to_bytes(time) {
                    Some(bytes) => Some(gst::GenericFormattedValue::Bytes(bytes)),
                    None => None,
                }
            }
            _ => None,
        }
    }
}

pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
    gst::Element::register(
        Some(plugin),
        "cdgparse",
        gst::Rank::Primary,
        CdgParse::get_type(),
    )
}
<commit_msg>cdgparse: fix time to bytes None conversion<commit_after>// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
//
// 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.

use glib;
use glib::subclass;
use glib::subclass::prelude::*;
use gst;
use gst::subclass::prelude::*;
use gst::SECOND_VAL;
use gst_base::prelude::*;
use gst_base::subclass::prelude::*;
use gstreamer::format::Bytes;
use gstreamer_base as gst_base;

use crate::constants::{
    CDG_COMMAND, CDG_HEIGHT, CDG_MASK, CDG_PACKET_PERIOD, CDG_PACKET_SIZE, CDG_WIDTH,
};

const CDG_CMD_MEMORY_PRESET: u8 = 1;

struct CdgParse {
    cat: gst::DebugCategory,
}

impl ObjectSubclass for CdgParse {
    const NAME: &'static str = "CdgParse";
    type ParentType = gst_base::BaseParse;
    type Instance = gst::subclass::ElementInstanceStruct<Self>;
    type Class = subclass::simple::ClassStruct<Self>;

    glib_object_subclass!();

    fn new() -> Self {
        Self {
            cat: gst::DebugCategory::new(
                "cdgparse",
                gst::DebugColorFlags::empty(),
                Some("CDG parser"),
            ),
        }
    }

    fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
        klass.set_metadata(
            "CDG parser",
            "Codec/Parser/Video",
            "CDG parser",
            "Guillaume Desmottes <guillaume.desmottes@collabora.com>",
        );

        let sink_caps = gst::Caps::new_simple("video/x-cdg", &[]);
        let sink_pad_template = gst::PadTemplate::new(
            "sink",
            gst::PadDirection::Sink,
            gst::PadPresence::Always,
            &sink_caps,
        )
        .unwrap();
        klass.add_pad_template(sink_pad_template);

        let src_caps = gst::Caps::new_simple(
            "video/x-cdg",
            &[
                ("width", &(CDG_WIDTH as i32)),
                ("height", &(CDG_HEIGHT as i32)),
                ("framerate", &gst::Fraction::new(0, 1)),
                ("parsed", &true),
            ],
        );
        let src_pad_template = gst::PadTemplate::new(
            "src",
            gst::PadDirection::Src,
            gst::PadPresence::Always,
            &src_caps,
        )
        .unwrap();
        klass.add_pad_template(src_pad_template);
    }
}

impl ObjectImpl for CdgParse {
    glib_object_impl!();
}

impl ElementImpl for CdgParse {}

fn bytes_to_time(bytes: u64) -> gst::ClockTime {
    let nb = bytes / CDG_PACKET_SIZE as u64;
    let ns = nb.mul_div_round(SECOND_VAL, CDG_PACKET_PERIOD).unwrap();

    gst::ClockTime::from_nseconds(ns)
}

fn time_to_bytes(time: gst::ClockTime) -> Bytes {
    match time.nseconds() {
        Some(time) => {
            let bytes = time.mul_div_round(CDG_PACKET_PERIOD * CDG_PACKET_SIZE as u64, SECOND_VAL);
            Bytes(bytes)
        }
        None => Bytes(None),
    }
}

impl BaseParseImpl for CdgParse {
    fn start(&self, element: &gst_base::BaseParse) -> Result<(), gst::ErrorMessage> {
        element.set_min_frame_size(CDG_PACKET_SIZE as u32);

        /* Set duration */
        let mut query = gst::Query::new_duration(gst::Format::Bytes);
        let pad = element.get_src_pad();
        if pad.query(&mut query) {
            let size = query.get_result().get_value() as u64;
            let duration = bytes_to_time(size);
            element.set_duration(duration, 0);
        }

        Ok(())
    }

    fn handle_frame(
        &self,
        element: &gst_base::BaseParse,
        frame: gst_base::BaseParseFrame,
    ) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
        let pad = element.get_src_pad();
        if pad.get_current_caps().is_none() {
            // Set src pad caps
            let src_caps = gst::Caps::new_simple(
                "video/x-cdg",
                &[
                    ("width", &(CDG_WIDTH as i32)),
                    ("height", &(CDG_HEIGHT as i32)),
                    ("framerate", &gst::Fraction::new(0, 1)),
                    ("parsed", &true),
                ],
            );

            pad.push_event(gst::Event::new_caps(&src_caps).build());
        }

        // Scan for CDG instruction
        let input = frame.get_buffer().unwrap();
        let skip = {
            let map = input.map_readable().ok_or_else(|| {
                gst_element_error!(
                    element,
                    gst::CoreError::Failed,
                    ["Failed to map input buffer readable"]
                );
                gst::FlowError::Error
            })?;
            let data = map.as_slice();

            data.iter()
                .enumerate()
                .find(|(_, byte)| (*byte & CDG_MASK == CDG_COMMAND))
                .map(|(i, _)| i)
                .unwrap_or(input.get_size()) // skip the whole buffer
                as u32
        };

        if skip != 0 {
            // Skip to the start of the CDG packet
            return Ok((gst::FlowSuccess::Ok, skip));
        }

        let keyframe = {
            let map = input.map_readable().ok_or_else(|| {
                gst_element_error!(
                    element,
                    gst::CoreError::Failed,
                    ["Failed to map input buffer readable"]
                );
                gst::FlowError::Error
            })?;
            let data = map.as_slice();

            // consider memory preset as keyframe as it clears the screen
            data[1] & CDG_MASK == CDG_CMD_MEMORY_PRESET
        };

        let pts = bytes_to_time(frame.get_offset() as u64);
        let buffer = frame.get_buffer().unwrap();
        buffer.set_pts(pts);

        if !keyframe {
            buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
        }

        gst_debug!(self.cat, obj: element, "Found frame pts={}", pts);

        element.finish_frame(frame, CDG_PACKET_SIZE as u32)?;

        Ok((gst::FlowSuccess::Ok, skip))
    }

    fn convert<V: Into<gst::GenericFormattedValue>>(
        &self,
        _element: &gst_base::BaseParse,
        src_val: V,
        dest_format: gst::Format,
    ) -> Option<gst::GenericFormattedValue> {
        let src_val = src_val.into();

        match (src_val, dest_format) {
            (gst::GenericFormattedValue::Bytes(bytes), gst::Format::Time) => Some(
                gst::GenericFormattedValue::Time(bytes_to_time(bytes.unwrap())),
            ),
            (gst::GenericFormattedValue::Time(time), gst::Format::Bytes) => {
                Some(time_to_bytes(time).into())
            }
            _ => None,
        }
    }
}

pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
    gst::Element::register(
        Some(plugin),
        "cdgparse",
        gst::Rank::Primary,
        CdgParse::get_type(),
    )
}
<|endoftext|>


<commit_before>// Copyright 2015 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.

use cmp::Ordering;
use libc;
use time::Duration;

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
                              (self.t.tv_nsec - other.t.tv_nsec) as u32)
            } else {
                Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
                              other.t.tv_nsec as u32)
            })
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn add_duration(&self, other: &Duration) -> Timespec {
        let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
        let mut secs = secs.expect("overflow when adding duration to time");

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1).expect("overflow when adding \
                                               duration to time");
        }
        Timespec {
            t: libc::timespec {
                tv_sec: secs as libc::time_t,
                tv_nsec: nsec as libc::c_long,
            },
        }
    }

    fn sub_duration(&self, other: &Duration) -> Timespec {
        let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
        let mut secs = secs.expect("overflow when subtracting duration \
                                    from time");

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1).expect("overflow when subtracting \
                                               duration from time");
        }
        Timespec {
            t: libc::timespec {
                tv_sec: secs as libc::time_t,
                tv_nsec: nsec as libc::c_long,
            },
        }
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use fmt;
    use libc;
    use sync::Once;
    use sys::cvt;
    use sys_common::mul_div_u64;
    use time::Duration;

    use super::NSEC_PER_SEC;
    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
    pub struct Instant {
        t: u64
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: unsafe { libc::mach_absolute_time() } }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            let info = info();
            let diff = self.t.checked_sub(other.t)
                           .expect("second instant is later than self");
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_add(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_sub(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use ptr;

            let mut s = libc::timeval {
                tv_sec: 0,
                tv_usec: 0,
            };
            cvt(unsafe {
                libc::gettimeofday(&mut s, ptr::null_mut())
            }).unwrap();
            return SystemTime::from(s)
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    fn dur2intervals(dur: &Duration) -> u64 {
        let info = info();
        let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
            nanos.checked_add(dur.subsec_nanos() as u64)
        }).expect("overflow converting duration to nanoseconds");
        mul_div_u64(nanos, info.denom as u64, info.numer as u64)
    }

    fn info() -> &'static libc::mach_timebase_info {
        static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
            numer: 0,
            denom: 0,
        };
        static ONCE: Once = Once::new();

        unsafe {
            ONCE.call_once(|| {
                libc::mach_timebase_info(&mut INFO);
            });
            &INFO
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use fmt;
    use libc;
    use sys::cvt;
    use time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
                panic!("other was less than the current instant")
            })
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.sub_duration(other) }
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Instant")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            }
        };
        cvt(unsafe {
            libc::clock_gettime(clock, &mut t.t)
        }).unwrap();
        t
    }
}
<commit_msg>Rollup merge of #41518 - tbu-:pr_fix_cp_error, r=sfackler<commit_after>// Copyright 2015 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.

use cmp::Ordering;
use libc;
use time::Duration;

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[derive(Copy, Clone)]
struct Timespec {
    t: libc::timespec,
}

impl Timespec {
    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
        if self >= other {
            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
                              (self.t.tv_nsec - other.t.tv_nsec) as u32)
            } else {
                Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
                              other.t.tv_nsec as u32)
            })
        } else {
            match other.sub_timespec(self) {
                Ok(d) => Err(d),
                Err(d) => Ok(d),
            }
        }
    }

    fn add_duration(&self, other: &Duration) -> Timespec {
        let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
        let mut secs = secs.expect("overflow when adding duration to time");

        // Nano calculations can't overflow because nanos are <1B which fit
        // in a u32.
        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
        if nsec >= NSEC_PER_SEC as u32 {
            nsec -= NSEC_PER_SEC as u32;
            secs = secs.checked_add(1).expect("overflow when adding \
                                               duration to time");
        }
        Timespec {
            t: libc::timespec {
                tv_sec: secs as libc::time_t,
                tv_nsec: nsec as libc::c_long,
            },
        }
    }

    fn sub_duration(&self, other: &Duration) -> Timespec {
        let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
        let mut secs = secs.expect("overflow when subtracting duration \
                                    from time");

        // Similar to above, nanos can't overflow.
        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
        if nsec < 0 {
            nsec += NSEC_PER_SEC as i32;
            secs = secs.checked_sub(1).expect("overflow when subtracting \
                                               duration from time");
        }
        Timespec {
            t: libc::timespec {
                tv_sec: secs as libc::time_t,
                tv_nsec: nsec as libc::c_long,
            },
        }
    }
}

impl PartialEq for Timespec {
    fn eq(&self, other: &Timespec) -> bool {
        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
    }
}

impl Eq for Timespec {}

impl PartialOrd for Timespec {
    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Timespec {
    fn cmp(&self, other: &Timespec) -> Ordering {
        let me = (self.t.tv_sec, self.t.tv_nsec);
        let other = (other.t.tv_sec, other.t.tv_nsec);
        me.cmp(&other)
    }
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use fmt;
    use libc;
    use sync::Once;
    use sys::cvt;
    use sys_common::mul_div_u64;
    use time::Duration;

    use super::NSEC_PER_SEC;
    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
    pub struct Instant {
        t: u64
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: unsafe { libc::mach_absolute_time() } }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            let info = info();
            let diff = self.t.checked_sub(other.t)
                           .expect("second instant is later than self");
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_add(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_sub(dur2intervals(other))
                       .expect("overflow when subtracting duration from instant"),
            }
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            use ptr;

            let mut s = libc::timeval {
                tv_sec: 0,
                tv_usec: 0,
            };
            cvt(unsafe {
                libc::gettimeofday(&mut s, ptr::null_mut())
            }).unwrap();
            return SystemTime::from(s)
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime::from(libc::timespec {
                tv_sec: t.tv_sec,
                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
            })
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    fn dur2intervals(dur: &Duration) -> u64 {
        let info = info();
        let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
            nanos.checked_add(dur.subsec_nanos() as u64)
        }).expect("overflow converting duration to nanoseconds");
        mul_div_u64(nanos, info.denom as u64, info.numer as u64)
    }

    fn info() -> &'static libc::mach_timebase_info {
        static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
            numer: 0,
            denom: 0,
        };
        static ONCE: Once = Once::new();

        unsafe {
            ONCE.call_once(|| {
                libc::mach_timebase_info(&mut INFO);
            });
            &INFO
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use fmt;
    use libc;
    use sys::cvt;
    use time::Duration;

    use super::Timespec;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: now(libc::CLOCK_MONOTONIC) }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
                panic!("other was less than the current instant")
            })
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.sub_duration(other) }
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Instant")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    #[cfg(not(target_os = "dragonfly"))]
    pub type clock_t = libc::c_int;
    #[cfg(target_os = "dragonfly")]
    pub type clock_t = libc::c_ulong;

    fn now(clock: clock_t) -> Timespec {
        let mut t = Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            }
        };
        cvt(unsafe {
            libc::clock_gettime(clock, &mut t.t)
        }).unwrap();
        t
    }
}
<|endoftext|>


<commit_before>//! Defines a rough glass material
//!
//! # Scene Usage Example
//! The rough glass material describes a thin glass surface material,
//! not a solid block of glass (there is no absorption of light). The glass requires
//! a reflective and emissive color along with a refrective index, eta and roughness.
//!
//! ```json
//! "materials": [
//!     {
//!         "name": "foggy_glass",
//!         "type": "rough_glass",
//!         "reflect": [1, 1, 1],
//!         "transmit": [1, 1, 1],
//!         "eta": 1.52,
//!         "roughness": 0.5,
//!     },
//!     ...
//! ]
//! ```

use std::sync::Arc;

use light_arena::Allocator;

use film::Colorf;
use geometry::Intersection;
use bxdf::{BxDF, BSDF, MicrofacetTransmission, TorranceSparrow};
use bxdf::microfacet::Beckmann;
use bxdf::fresnel::Dielectric;
use material::Material;
use texture::Texture;

/// The `RoughGlass` material describes specularly transmissive and reflective glass material
pub struct RoughGlass {
    reflect: Arc<Texture<Colorf> + Send + Sync>,
    transmit: Arc<Texture<Colorf> + Send + Sync>,
    eta: Arc<Texture<f32> + Send + Sync>,
    roughness: Arc<Texture<f32> + Send + Sync>,
}

impl RoughGlass {
    /// Create the `RoughGlass` material with the desired color and index of refraction
    /// `reflect`: color of reflected light
    /// `transmit`: color of transmitted light
    /// `eta`: refractive index of the material
    /// `roughness`: roughness of the material
    pub fn new(reflect: Arc<Texture<Colorf> + Send + Sync>,
               transmit: Arc<Texture<Colorf> + Send + Sync>,
               eta: Arc<Texture<f32> + Send + Sync>,
               roughness: Arc<Texture<f32> + Send + Sync>) -> RoughGlass
    {
        RoughGlass { reflect: reflect, transmit: transmit, eta: eta, roughness: roughness }
    }
}

impl Material for RoughGlass {
    fn bsdf<'a, 'b, 'c>(&self, hit: &Intersection<'a, 'b>,
                        alloc: &'c Allocator) -> BSDF<'c> where 'a: 'c {
        let reflect = self.reflect.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let transmit = self.transmit.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let eta = self.eta.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let roughness = self.roughness.sample(hit.dg.u, hit.dg.v, hit.dg.time);

        let mut num_bxdfs = 0;
        if !reflect.is_black() {
            num_bxdfs += 1;
        }
        if !transmit.is_black() {
            num_bxdfs += 1;
        }

        let bxdfs = alloc.alloc_slice::<&BxDF>(num_bxdfs);
        let mut i = 0;
        let fresnel = alloc <- Dielectric::new(1.0, eta);
        let microfacet = alloc <- Beckmann::new(roughness);
        if !reflect.is_black() {
            bxdfs[i] = alloc <- TorranceSparrow::new(&reflect, fresnel, microfacet);
            i += 1;
        }
        if !transmit.is_black() {
            println!("i = {}", i);
            bxdfs[i] = alloc <- MicrofacetTransmission::new(&transmit, fresnel, microfacet);
        }
        BSDF::new(bxdfs, eta, &hit.dg)
    }
}

<commit_msg>remove a print<commit_after>//! Defines a rough glass material
//!
//! # Scene Usage Example
//! The rough glass material describes a thin glass surface material,
//! not a solid block of glass (there is no absorption of light). The glass requires
//! a reflective and emissive color along with a refrective index, eta and roughness.
//!
//! ```json
//! "materials": [
//!     {
//!         "name": "foggy_glass",
//!         "type": "rough_glass",
//!         "reflect": [1, 1, 1],
//!         "transmit": [1, 1, 1],
//!         "eta": 1.52,
//!         "roughness": 0.5,
//!     },
//!     ...
//! ]
//! ```

use std::sync::Arc;

use light_arena::Allocator;

use film::Colorf;
use geometry::Intersection;
use bxdf::{BxDF, BSDF, MicrofacetTransmission, TorranceSparrow};
use bxdf::microfacet::Beckmann;
use bxdf::fresnel::Dielectric;
use material::Material;
use texture::Texture;

/// The `RoughGlass` material describes specularly transmissive and reflective glass material
pub struct RoughGlass {
    reflect: Arc<Texture<Colorf> + Send + Sync>,
    transmit: Arc<Texture<Colorf> + Send + Sync>,
    eta: Arc<Texture<f32> + Send + Sync>,
    roughness: Arc<Texture<f32> + Send + Sync>,
}

impl RoughGlass {
    /// Create the `RoughGlass` material with the desired color and index of refraction
    /// `reflect`: color of reflected light
    /// `transmit`: color of transmitted light
    /// `eta`: refractive index of the material
    /// `roughness`: roughness of the material
    pub fn new(reflect: Arc<Texture<Colorf> + Send + Sync>,
               transmit: Arc<Texture<Colorf> + Send + Sync>,
               eta: Arc<Texture<f32> + Send + Sync>,
               roughness: Arc<Texture<f32> + Send + Sync>) -> RoughGlass
    {
        RoughGlass { reflect: reflect, transmit: transmit, eta: eta, roughness: roughness }
    }
}

impl Material for RoughGlass {
    fn bsdf<'a, 'b, 'c>(&self, hit: &Intersection<'a, 'b>,
                        alloc: &'c Allocator) -> BSDF<'c> where 'a: 'c {
        let reflect = self.reflect.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let transmit = self.transmit.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let eta = self.eta.sample(hit.dg.u, hit.dg.v, hit.dg.time);
        let roughness = self.roughness.sample(hit.dg.u, hit.dg.v, hit.dg.time);

        let mut num_bxdfs = 0;
        if !reflect.is_black() {
            num_bxdfs += 1;
        }
        if !transmit.is_black() {
            num_bxdfs += 1;
        }

        let bxdfs = alloc.alloc_slice::<&BxDF>(num_bxdfs);
        let mut i = 0;
        let fresnel = alloc <- Dielectric::new(1.0, eta);
        let microfacet = alloc <- Beckmann::new(roughness);
        if !reflect.is_black() {
            bxdfs[i] = alloc <- TorranceSparrow::new(&reflect, fresnel, microfacet);
            i += 1;
        }
        if !transmit.is_black() {
            bxdfs[i] = alloc <- MicrofacetTransmission::new(&transmit, fresnel, microfacet);
        }
        BSDF::new(bxdfs, eta, &hit.dg)
    }
}

<|endoftext|>


<commit_before>use crate::io::util::{BufReader, BufWriter};
use crate::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};

use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};

pin_project! {
    /// Wraps a type that is [`AsyncWrite`] and [`AsyncRead`], and buffers its input and output.
    ///
    /// It can be excessively inefficient to work directly with something that implements [`AsyncWrite`]
    /// and [`AsyncRead`]. For example, every `write`, however small, has to traverse the syscall
    /// interface, and similarly, every read has to do the same. The [`BufWriter`] and [`BufReader`]
    /// types aid with these problems respectively, but do so in only one direction. `BufStream` wraps
    /// one in the other so that both directions are buffered. See their documentation for details.
    #[derive(Debug)]
    #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
    pub struct BufStream<RW> {
        #[pin]
        inner: BufReader<BufWriter<RW>>,
    }
}

impl<RW: AsyncRead + AsyncWrite> BufStream<RW> {
    /// Wraps a type in both [`BufWriter`] and [`BufReader`].
    ///
    /// See the documentation for those types and [`BufStream`] for details.
    pub fn new(stream: RW) -> BufStream<RW> {
        BufStream {
            inner: BufReader::new(BufWriter::new(stream)),
        }
    }

    /// Creates a `BufStream` with the specified [`BufReader`] capacity and [`BufWriter`]
    /// capacity.
    ///
    /// See the documentation for those types and [`BufStream`] for details.
    pub fn with_capacity(
        reader_capacity: usize,
        writer_capacity: usize,
        stream: RW,
    ) -> BufStream<RW> {
        BufStream {
            inner: BufReader::with_capacity(
                reader_capacity,
                BufWriter::with_capacity(writer_capacity, stream),
            ),
        }
    }

    /// Gets a reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_ref(&self) -> &RW {
        self.inner.get_ref().get_ref()
    }

    /// Gets a mutable reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_mut(&mut self) -> &mut RW {
        self.inner.get_mut().get_mut()
    }

    /// Gets a pinned mutable reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut RW> {
        self.project().inner.get_pin_mut().get_pin_mut()
    }

    /// Consumes this `BufStream`, returning the underlying I/O object.
    ///
    /// Note that any leftover data in the internal buffer is lost.
    pub fn into_inner(self) -> RW {
        self.inner.into_inner().into_inner()
    }
}

impl<RW> From<BufReader<BufWriter<RW>>> for BufStream<RW> {
    fn from(b: BufReader<BufWriter<RW>>) -> Self {
        BufStream { inner: b }
    }
}

impl<RW> From<BufWriter<BufReader<RW>>> for BufStream<RW> {
    fn from(b: BufWriter<BufReader<RW>>) -> Self {
        // we need to "invert" the reader and writer
        let BufWriter {
            inner:
                BufReader {
                    inner,
                    buf: rbuf,
                    pos,
                    cap,
                    seek_state: rseek_state,
                },
            buf: wbuf,
            written,
            seek_state: wseek_state,
        } = b;

        BufStream {
            inner: BufReader {
                inner: BufWriter {
                    inner,
                    buf: wbuf,
                    written,
                    seek_state: wseek_state,
                },
                buf: rbuf,
                pos,
                cap,
                seek_state: rseek_state,
            },
        }
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncWrite for BufStream<RW> {
    fn poll_write(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &[u8],
    ) -> Poll<io::Result<usize>> {
        self.project().inner.poll_write(cx, buf)
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        self.project().inner.poll_flush(cx)
    }

    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        self.project().inner.poll_shutdown(cx)
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncRead for BufStream<RW> {
    fn poll_read(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> Poll<io::Result<()>> {
        self.project().inner.poll_read(cx, buf)
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncBufRead for BufStream<RW> {
    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
        self.project().inner.poll_fill_buf(cx)
    }

    fn consume(self: Pin<&mut Self>, amt: usize) {
        self.project().inner.consume(amt)
    }
}

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

    #[test]
    fn assert_unpin() {
        crate::is_unpin::<BufStream<()>>();
    }
}
<commit_msg>io: impl AsyncSeek for BufStream (#3810)<commit_after>use crate::io::util::{BufReader, BufWriter};
use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, ReadBuf};

use pin_project_lite::pin_project;
use std::io::{self, SeekFrom};
use std::pin::Pin;
use std::task::{Context, Poll};

pin_project! {
    /// Wraps a type that is [`AsyncWrite`] and [`AsyncRead`], and buffers its input and output.
    ///
    /// It can be excessively inefficient to work directly with something that implements [`AsyncWrite`]
    /// and [`AsyncRead`]. For example, every `write`, however small, has to traverse the syscall
    /// interface, and similarly, every read has to do the same. The [`BufWriter`] and [`BufReader`]
    /// types aid with these problems respectively, but do so in only one direction. `BufStream` wraps
    /// one in the other so that both directions are buffered. See their documentation for details.
    #[derive(Debug)]
    #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
    pub struct BufStream<RW> {
        #[pin]
        inner: BufReader<BufWriter<RW>>,
    }
}

impl<RW: AsyncRead + AsyncWrite> BufStream<RW> {
    /// Wraps a type in both [`BufWriter`] and [`BufReader`].
    ///
    /// See the documentation for those types and [`BufStream`] for details.
    pub fn new(stream: RW) -> BufStream<RW> {
        BufStream {
            inner: BufReader::new(BufWriter::new(stream)),
        }
    }

    /// Creates a `BufStream` with the specified [`BufReader`] capacity and [`BufWriter`]
    /// capacity.
    ///
    /// See the documentation for those types and [`BufStream`] for details.
    pub fn with_capacity(
        reader_capacity: usize,
        writer_capacity: usize,
        stream: RW,
    ) -> BufStream<RW> {
        BufStream {
            inner: BufReader::with_capacity(
                reader_capacity,
                BufWriter::with_capacity(writer_capacity, stream),
            ),
        }
    }

    /// Gets a reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_ref(&self) -> &RW {
        self.inner.get_ref().get_ref()
    }

    /// Gets a mutable reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_mut(&mut self) -> &mut RW {
        self.inner.get_mut().get_mut()
    }

    /// Gets a pinned mutable reference to the underlying I/O object.
    ///
    /// It is inadvisable to directly read from the underlying I/O object.
    pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut RW> {
        self.project().inner.get_pin_mut().get_pin_mut()
    }

    /// Consumes this `BufStream`, returning the underlying I/O object.
    ///
    /// Note that any leftover data in the internal buffer is lost.
    pub fn into_inner(self) -> RW {
        self.inner.into_inner().into_inner()
    }
}

impl<RW> From<BufReader<BufWriter<RW>>> for BufStream<RW> {
    fn from(b: BufReader<BufWriter<RW>>) -> Self {
        BufStream { inner: b }
    }
}

impl<RW> From<BufWriter<BufReader<RW>>> for BufStream<RW> {
    fn from(b: BufWriter<BufReader<RW>>) -> Self {
        // we need to "invert" the reader and writer
        let BufWriter {
            inner:
                BufReader {
                    inner,
                    buf: rbuf,
                    pos,
                    cap,
                    seek_state: rseek_state,
                },
            buf: wbuf,
            written,
            seek_state: wseek_state,
        } = b;

        BufStream {
            inner: BufReader {
                inner: BufWriter {
                    inner,
                    buf: wbuf,
                    written,
                    seek_state: wseek_state,
                },
                buf: rbuf,
                pos,
                cap,
                seek_state: rseek_state,
            },
        }
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncWrite for BufStream<RW> {
    fn poll_write(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &[u8],
    ) -> Poll<io::Result<usize>> {
        self.project().inner.poll_write(cx, buf)
    }

    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        self.project().inner.poll_flush(cx)
    }

    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
        self.project().inner.poll_shutdown(cx)
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncRead for BufStream<RW> {
    fn poll_read(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> Poll<io::Result<()>> {
        self.project().inner.poll_read(cx, buf)
    }
}

/// Seek to an offset, in bytes, in the underlying stream.
///
/// The position used for seeking with `SeekFrom::Current(_)` is the
/// position the underlying stream would be at if the `BufStream` had no
/// internal buffer.
///
/// Seeking always discards the internal buffer, even if the seek position
/// would otherwise fall within it. This guarantees that calling
/// `.into_inner()` immediately after a seek yields the underlying reader
/// at the same position.
///
/// See [`AsyncSeek`] for more details.
///
/// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
/// where `n` minus the internal buffer length overflows an `i64`, two
/// seeks will be performed instead of one. If the second seek returns
/// `Err`, the underlying reader will be left at the same position it would
/// have if you called `seek` with `SeekFrom::Current(0)`.
impl<RW: AsyncRead + AsyncWrite + AsyncSeek> AsyncSeek for BufStream<RW> {
    fn start_seek(self: Pin<&mut Self>, position: SeekFrom) -> io::Result<()> {
        self.project().inner.start_seek(position)
    }

    fn poll_complete(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
        self.project().inner.poll_complete(cx)
    }
}

impl<RW: AsyncRead + AsyncWrite> AsyncBufRead for BufStream<RW> {
    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
        self.project().inner.poll_fill_buf(cx)
    }

    fn consume(self: Pin<&mut Self>, amt: usize) {
        self.project().inner.consume(amt)
    }
}

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

    #[test]
    fn assert_unpin() {
        crate::is_unpin::<BufStream<()>>();
    }
}
<|endoftext|>


<commit_before>
#[allow(dead_code)]
pub fn multiples() -> i64 {
    23
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn example_data() {
        assert_eq!(multiples(), 23);
    }
}
<commit_msg>first solved in non-functional way<commit_after>
#[allow(dead_code)]
pub fn multiples() -> i64 {
    let range = 0..10;
    let divisible = range.filter( |x| x % 3 == 0 || x % 5 == 0);
    let mut sum = 0;
    for x in divisible {
        sum = sum + x;
    }
    sum
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn example_data() {
        assert_eq!(multiples(), 23);
    }
}
<|endoftext|>