<commit_before>use common::*;
use std::io::{Read, Write, Result};

mod events;
mod memory;
mod modes;
mod opcodes;
mod registers;

use self::memory::*;
use self::modes::*;
use self::opcodes::*;
use self::registers::*;

pub struct VM<R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory,
}

impl<R: Read, W: Write> VM<R, W> {
    pub fn new(input: R, output: W, executable: Data) -> Self {
        let memory = Memory::from_executable(executable);

        VM {
            input: input,
            output: output,
            registers: [0; REGISTERS],
            memory: memory,
        }
    }

    pub fn run(&mut self) {
        self.set_register(PC, CODE_OFFSET as Word);

        let mut args = vec![];
        while self.memory.is_in_code(self.get_register(PC)) {
            self.fetch()
                .decode(&mut args)
                .execute(&args)
                .process_events();
            args.clear();
        }
    }

    pub fn stack(&self) -> DataSlice {
        let sp = self.get_register(SP);
        self.memory.stack(sp)
    }

    pub fn data(&self) -> DataSlice {
        self.memory.data()
    }

    fn fetch(&mut self) -> &mut Self {
        let code_offset = self.get_register(PC);
        let opcode = self.memory.get(code_offset) as Word;
        self.set_register(IR, opcode);
        self.increment_register(PC);
        self
    }

    fn decode(&mut self, args: &mut Words) -> &mut Self {
        unimplemented!()
        // match self.get_register(IR) as u8 {
        //     MOV => {
        //         args.push(self.read_memory());
        //         args.push(self.read_memory());
        //     }
        //     _ => unimplemented!(),
        // }
        // self
    }

    fn execute(&mut self, args: WordsSlice) -> &mut Self {
        unimplemented!()
    }

    fn process_events(&mut self) {
        unimplemented!()
    }

    // fn read_memory(&mut self) -> Word {
    //     let code_offset = self.get_register(PC);
    //     let mode = self.memory.get(code_offset);
    //     self.increment_register(PC);
    //
    //     match mode {
    //         REG => {
    //             let code_offset = self.get_register(PC);
    //             self.increment_register(PC);
    //             let register_id = self.memory.get(code_offset);
    //             self.get_register(register_id)
    //         }
    //         PTR => unimplemented!(),
    //         PTR_WITH_OFFSET => unimplemented!(),
    //         VALUE => {
    //             let code_offset = self.get_register(PC) as usize;
    //             self.increment_register(PC);
    //             let value = self.memory.read_word(code_offset);
    //             for _ in 0..WORD_SIZE {
    //                 self.increment_register(PC);
    //             }
    //             value
    //         }
    //         _ => unreachable!(),
    //     }
    // }

    fn get_register(&self, id: u8) -> Word {
        self.registers[id as usize]
    }

    fn set_register(&mut self, id: u8, value: Word) {
        self.registers[id as usize] = value;
    }

    fn increment_register(&mut self, id: u8) {
        self.registers[id as usize] += 1;
    }
}

#[cfg(test)]
mod tests {
    use self::events::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        assert!(run(&[], vec![]).0.is_empty());

        {
            let mut executable = vec![
                0, 0,
                PUSH, 3,
                PUSH, 4,
                ADD];     // pop 2 bytes, add and push
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[7], vm.stack());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 10,
                DEC,
                INT, OUTPUT,
                JNE, 0,  4, 0];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[9, 8, 7, 6, 5, 4, 3, 2, 1, 0], output.as_slice());
            assert_eq!([0], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                         // offset
                LOAD, PTR_WITH_OFFSET, 20, 0,    // data segment
                INT, OUTPUT,
                JE, 0,  19, 0,
                POP,
                INC,
                JMP, 4, 0,
                NOP,
                3, 2, 1, 0];
            let data_size = 4;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(4, vm.data().len());
            assert_eq!(&[0], vm.stack());
            assert_eq!(&[3, 2, 1], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                INT, INPUT,
                INT, OUTPUT,
                JNE, 0,  2, 0];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[0, 1, 2, 3], vm.stack());
            assert_eq!(&[3, 2, 1, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 4,
                PUSH, 12,
                DIV];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Unknown Error", output.as_slice());
            assert_eq!(&[3], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,
                PUSH, 1,
                DIV];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Unknown Error", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                POP];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 255, 255];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 6, 0,
                123];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[123], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                                             // do
                INT, INPUT,                  //   d = read
                CALL, PTR, 20, 0,            //   d = f(d)
                INT, OUTPUT,                 //   print a
                JE, 0,  18, 0,               // while d != 0
                POP,
                JMP, 2, 0,                   // goto do
                INT, TERMINATE,              // exit

                // label f
                PUSH, 2,
                MUL,                         // a = a * 2
                RET];

            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[6, 4, 2, 0], output.as_slice());
        }
    }

    fn run(input: DataSlice,
           executable: Data)
           -> (Data, VM<BufReader<DataSlice>, BufWriter<Data>>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output, executable);
        vm.run();

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm)
    }
}
<commit_msg>bugfix<commit_after>use common::*;
use std::io::{Read, Write, Result};

mod events;
mod memory;
mod modes;
mod opcodes;
mod registers;

use self::memory::*;
use self::modes::*;
use self::opcodes::*;
use self::registers::*;

pub struct VM<R: Read, W: Write> {
    input: R,
    output: W,

    registers: Registers,
    memory: Memory,
}

impl<R: Read, W: Write> VM<R, W> {
    pub fn new(input: R, output: W, executable: Data) -> Self {
        let memory = Memory::from_executable(executable);

        VM {
            input: input,
            output: output,
            registers: [0; REGISTERS],
            memory: memory,
        }
    }

    pub fn run(&mut self) {
        self.set_register(PC, CODE_OFFSET as Word);

        let mut args = vec![];
        while self.memory.is_in_code(self.get_register(PC)) {
            self.fetch()
                .decode(&mut args)
                .execute(&args)
                .process_events();
            args.clear();
        }
    }

    pub fn stack(&self) -> DataSlice {
        let sp = self.get_register(SP);
        self.memory.stack(sp)
    }

    pub fn data(&self) -> DataSlice {
        self.memory.data()
    }

    fn fetch(&mut self) -> &mut Self {
        let code_offset = self.get_register(PC);
        let opcode = self.memory.get(code_offset) as Word;
        self.set_register(IR, opcode);
        self.increment_register(PC);
        self
    }

    fn decode(&mut self, args: &mut Words) -> &mut Self {
        unimplemented!()
        // match self.get_register(IR) as u8 {
        //     MOV => {
        //         args.push(self.read_memory());
        //         args.push(self.read_memory());
        //     }
        //     _ => unimplemented!(),
        // }
        // self
    }

    fn execute(&mut self, args: WordsSlice) -> &mut Self {
        unimplemented!()
    }

    fn process_events(&mut self) {
        unimplemented!()
    }

    // fn read_memory(&mut self) -> Word {
    //     let code_offset = self.get_register(PC);
    //     let mode = self.memory.get(code_offset);
    //     self.increment_register(PC);
    //
    //     match mode {
    //         REG => {
    //             let code_offset = self.get_register(PC);
    //             self.increment_register(PC);
    //             let register_id = self.memory.get(code_offset);
    //             self.get_register(register_id)
    //         }
    //         PTR => unimplemented!(),
    //         PTR_WITH_OFFSET => unimplemented!(),
    //         VALUE => {
    //             let code_offset = self.get_register(PC) as usize;
    //             self.increment_register(PC);
    //             let value = self.memory.read_word(code_offset);
    //             for _ in 0..WORD_SIZE {
    //                 self.increment_register(PC);
    //             }
    //             value
    //         }
    //         _ => unreachable!(),
    //     }
    // }

    fn get_register(&self, id: u8) -> Word {
        self.registers[id as usize]
    }

    fn set_register(&mut self, id: u8, value: Word) {
        self.registers[id as usize] = value;
    }

    fn increment_register(&mut self, id: u8) {
        self.registers[id as usize] += 1;
    }
}

#[cfg(test)]
mod tests {
    use self::events::*;
    use std::io::{BufReader, BufWriter};
    use super::*;

    #[cfg_attr(rustfmt, rustfmt_skip)]
    #[test]
    fn simple() {
        {
            let (output, vm) = run(&[], vec![]);

            assert!(output.is_empty());
            assert!(vm.stack().is_empty());
            assert!(vm.data().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 3,                       // b
                PUSH, 4,                       // a
                ADD];                          // pop 2 bytes,
                                               // add (a + b) and push
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[7], vm.stack());
            assert!(output.is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 10,                      // a
                DEC,                           // a--
                INT, OUTPUT,
                JNE, 6, 0];                    // a != b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[9, 8, 7, 6, 5, 4, 3, 2, 1, 0], output.as_slice());
            assert_eq!([0], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                PUSH, 0,                       // offset

                // label loop
                LOAD, PTR_WITH_OFFSET, 21, 0,  // d = [data segment + offset]
                INT, OUTPUT,                   // print d
                JE, 20, 0,                     // if d == zero: goto end
                POP,                           // pop d
                INC,                           // offset++
                JMP, 6, 0,                     // goto loop

                // label end
                NOP,                           // optional
                3, 2, 1, 0];
            let data_size = 4;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(4, vm.data().len());
            assert_eq!(&[0], vm.stack());
            assert_eq!(&[3, 2, 1], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b

                // label loop
                INT, INPUT,                    // a
                INT, OUTPUT,                   // print a
                JE, 15, 0,                     // if a == b: goto end
                POP,                           // remove a
                JMP, 4, 0                      // goto loop

                // label end
                // NOP                         // optional
                ];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[0, 0], vm.stack());
            assert_eq!(&[3, 2, 1, 0], output.as_slice());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 4,                       // b
                PUSH, 12,                      // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert!(output.is_empty());
            assert_eq!(&[3], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // b
                PUSH, 1,                       // a
                DIV];                          // a / b
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Unknown Error", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                POP];
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 255, 255];          // access violation
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 2, 0];              // try to load code segment
                                               // as data segment
            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(b"Segfault", output.as_slice());
            assert!(vm.stack().is_empty());
        }

        {
            let mut executable = vec![
                0, 0,
                LOAD, PTR, 6, 0,
                123];
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[123], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // zero
                                               // loop:
                INT, INPUT,                    //   x = read
                CALL, PTR, 20, 0,              //   x = f(x)
                INT, OUTPUT,                   //   print x
                JE, 18, 0,                     // if x == zero: goto exit
                POP,                           // pop x
                JMP, 2, 0,                     // goto loop
                INT, TERMINATE,                // exit:

                                               // f:
                PUSH, 2,
                MUL,                           // a = a * 2
                RET];

            let code_size = executable.len() as u8;
            executable[0] = code_size;

            let input = [3, 2, 1, 0];
            let (output, vm) = run(&input, executable);

            assert_eq!(&[6, 4, 2, 0], output.as_slice());
            assert_eq!(&[0, 0], vm.stack());
        }

        {
            let mut executable = vec![
                0, 0,
                PUSH, 0,                       // i
                                               // loop:
                LOAD, 19, 0,                   // x
                JLE, 19, 0,                    // if x <= i goto: end
                DEC,
                STORE, 19, 0,                  // x
                POP,
                INC,
                JMP, 4, 0,                     // goto loop
                                               // end:
                5];                            // x
            let data_size = 1;
            let code_size = executable.len() as u8 - data_size;
            executable[0] = code_size;

            let (output, vm) = run(&[], executable);

            assert_eq!(&[3], vm.stack());
            assert_eq!(&[2], vm.data());
        }
    }

    fn run(input: DataSlice,
           executable: Data)
           -> (Data, VM<BufReader<DataSlice>, BufWriter<Data>>) {
        let input = BufReader::new(input);

        let output: Data = vec![];
        let output = BufWriter::new(output);

        let mut vm = VM::new(input, output, executable);
        vm.run();

        let output = vm.output
            .get_mut()
            .by_ref()
            .iter()
            .map(|x| *x)
            .collect::<Data>();

        (output, vm)
    }
}
<|endoftext|>


<commit_before>

use super::{BaseNum, PartialOrd};
use std::ops::{Div, Mul};
use num_traits::Zero;

/// A two-dimensional dimension.
pub struct Dimension2<T> {
    pub width: T,
    pub height: T,
}

pub type Dimension2f = Dimension2<super::DefaultFloat>;
pub type Dimension2i = Dimension2<super::DefaultInt>;
pub type Dimension2u = Dimension2<super::DefaultUnsigned>;

impl<T: BaseNum> Dimension2<T> {
    pub fn new(width: T, height: T) -> Self {
        Dimension2 {
            width: width,
            height: height,
        }
    }
    ///
    pub fn area(&self) -> <T as Mul>::Output {
        self.width * self.height
    }
    pub fn scale(&self, scale: T) -> Dimension2<T> {
        Dimension2 {
            width: self.width * scale,
            height: self.height * scale,
        }
    }
    pub fn aspect_ratio(&self) -> <T as Div>::Output {
      //  assert!(!self.height.Zero::is_zero());
        self.width / self.height
    }
    pub fn fitting(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_min(other.width / self.width, other.height / self.height);
        self.scale(scale)

    }
    pub fn filling(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_max(other.width / self.width, other.height / self.height);
        self.scale(scale)
    }
}

#[test]
fn test_area() {
    let test1 = Dimension2(width: 3, height: 5);
    let test2 = Dimension2(width: 0, height: 0);

    assert_eq!(test2.area(), 0);
    assert_eq!(test1.area(), 15);
}
fn test_scale(){
    let test1 = Dimension2(width: 3, height: 5);
    let test2 = Dimension2(width: 0, height: 0);
    let scale = 4;

    test1.scale(scale);

}
<commit_msg>added some Test Functions<commit_after>

use super::{BaseNum, PartialOrd};
use std::ops::{Div, Mul};
use num_traits::Zero;

/// A two-dimensional dimension.
#[derive(Debug)]
pub struct Dimension2<T> {
    pub width: T,
    pub height: T,
}

pub type Dimension2f = Dimension2<super::DefaultFloat>;
pub type Dimension2i = Dimension2<super::DefaultInt>;
pub type Dimension2u = Dimension2<super::DefaultUnsigned>;

impl<T: BaseNum> Dimension2<T> {
    pub fn new(width: T, height: T) -> Self {
        Dimension2 {
            width: width,
            height: height,
        }
    }
    ///
    pub fn area(&self) -> <T as Mul>::Output {
        self.width * self.height
    }
    pub fn scale(&self, scale: T) -> Dimension2<T> {
        Dimension2 {
            width: self.width * scale,
            height: self.height * scale,
        }
    }
    pub fn aspect_ratio(&self) -> <T as Div>::Output {
        // assert!(self.height.Zero::is_zero());
        self.width / self.height
    }
    pub fn fitting(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_min(other.width / self.width, other.height / self.height);
        self.scale(scale)

    }
    pub fn filling(&self, other: Dimension2<T>) -> Dimension2<T> {
        let scale = PartialOrd::partial_max(other.width / self.width, other.height / self.height);
        self.scale(scale)
    }
}

#[test]
fn test_area() {
    let test1 = Dimension2 {
        width: 3,
        height: 5,
    };
    let test2 = Dimension2 {
        width: 0,
        height: 0,
    };
    assert_eq!(test2.area(), 0);
    assert_eq!(test1.area(), 15);
}
fn test_scale() {
    let test1 = Dimension2 {
        width: 3,
        height: 5,
    };
    let test2 = Dimension2 {
        width: 12,
        height: 20,
    };
    let scale = 4;
    let scale1 = 0;
    assert_eq!(test1.scale(scale).width, 12);
    assert_eq!(test2.scale(scale1).width, 0);
}
fn test_aspect_ratio() {}
<|endoftext|>


<commit_before>use super::utils::types::Hash256;
use super::attestation_record::AttestationRecord;
use super::ssz;

const SSZ_BLOCK_LENGTH: usize = 192;

pub struct Block {
    pub parent_hash: Hash256,
    pub slot_number: u64,
    pub randao_reveal: Hash256,
    pub attestations: Vec<AttestationRecord>,
    pub pow_chain_ref: Hash256,
    pub active_state_root: Hash256,
    pub crystallized_state_root: Hash256,
}

impl Block {
    pub fn zero() -> Self {
        Self {
            parent_hash: Hash256::zero(),
            slot_number: 0,
            randao_reveal: Hash256::zero(),
            attestations: vec![],
            pow_chain_ref: Hash256::zero(),
            active_state_root: Hash256::zero(),
            crystallized_state_root: Hash256::zero(),
        }
    }

    // Not sure if this will be useful, leaving it here for the
    // time being.
    pub fn ssz_encode_without_attestations(&self)
        -> [u8; SSZ_BLOCK_LENGTH]
    {
        let mut s = ssz::SszStream::new();
        s.append(&self.parent_hash);
        s.append(&self.slot_number);
        s.append(&self.randao_reveal);
        s.append(&self.pow_chain_ref);
        s.append(&self.active_state_root);
        s.append(&self.crystallized_state_root);
        let vec = s.drain();
        let mut encoded = [0; SSZ_BLOCK_LENGTH];
        encoded.copy_from_slice(&vec); encoded
    }
}

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

    #[test]
    fn test_block_zero() {
        let b = Block::zero();
        assert!(b.parent_hash.is_zero());
        assert_eq!(b.slot_number, 0);
        assert!(b.randao_reveal.is_zero());
        assert_eq!(b.attestations.len(), 0);
        assert!(b.pow_chain_ref.is_zero());
        assert!(b.active_state_root.is_zero());
        assert!(b.crystallized_state_root.is_zero());
    }
}
<commit_msg>Update ssz for Block<commit_after>use super::utils::types::Hash256;
use super::attestation_record::AttestationRecord;
use super::ssz::{ Encodable, SszStream };

const SSZ_BLOCK_LENGTH: usize = 192;

pub struct Block {
    pub parent_hash: Hash256,
    pub slot_number: u64,
    pub randao_reveal: Hash256,
    pub attestations: Vec<AttestationRecord>,
    pub pow_chain_ref: Hash256,
    pub active_state_root: Hash256,
    pub crystallized_state_root: Hash256,
}

impl Block {
    pub fn zero() -> Self {
        Self {
            parent_hash: Hash256::zero(),
            slot_number: 0,
            randao_reveal: Hash256::zero(),
            attestations: vec![],
            pow_chain_ref: Hash256::zero(),
            active_state_root: Hash256::zero(),
            crystallized_state_root: Hash256::zero(),
        }
    }

    /// Return the bytes that should be signed in order to
    /// attest for this block.
    pub fn encode_for_signing(&self)
        -> [u8; SSZ_BLOCK_LENGTH]
    {
        let mut s = SszStream::new();
        s.append(&self.parent_hash);
        s.append(&self.slot_number);
        s.append(&self.randao_reveal);
        s.append(&self.pow_chain_ref);
        s.append(&self.active_state_root);
        s.append(&self.crystallized_state_root);
        let vec = s.drain();
        let mut encoded = [0; SSZ_BLOCK_LENGTH];
        encoded.copy_from_slice(&vec); encoded
    }
}

impl Encodable for Block {
    fn ssz_append(&self, s: &mut SszStream) {
        let mut s = SszStream::new();
        s.append(&self.parent_hash);
        s.append(&self.slot_number);
        s.append(&self.randao_reveal);
        s.append(&self.attestations);
        s.append(&self.pow_chain_ref);
        s.append(&self.active_state_root);
        s.append(&self.crystallized_state_root);
    }
}

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

    #[test]
    fn test_block_zero() {
        let b = Block::zero();
        assert!(b.parent_hash.is_zero());
        assert_eq!(b.slot_number, 0);
        assert!(b.randao_reveal.is_zero());
        assert_eq!(b.attestations.len(), 0);
        assert!(b.pow_chain_ref.is_zero());
        assert!(b.active_state_root.is_zero());
        assert!(b.crystallized_state_root.is_zero());
    }
}
<|endoftext|>


<commit_before>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

macro_rules! on_conflict_tuples {
    ($(
        $Tuple:tt {
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
        }
    )+) => {
        $(
            impl<_DB, _T, $($T),*> QueryFragment<_DB> for ConflictTarget<(_T, $($T),*)> where
                _DB: Backend + SupportsOnConflictClause,
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
                fn walk_ast(&self, mut out: AstPass<_DB>) -> QueryResult<()> {
                    out.push_sql(" (");
                    out.push_identifier(_T::NAME)?;
                    $(
                        out.push_sql(", ");
                        out.push_identifier($T::NAME)?;
                    )*
                    out.push_sql(")");
                    Ok(())
                }
            }

            impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
            }
        )*
    }
}

__diesel_for_each_tuple!(on_conflict_tuples);
<commit_msg>Allow also tuples with only one column as `ConflictTarget`<commit_after>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

impl<DB, T> QueryFragment<DB> for ConflictTarget<(T,)>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<(T,)> where T: Column {}

macro_rules! on_conflict_tuples {
    ($(
        $Tuple:tt {
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
        }
    )+) => {
        $(
            impl<_DB, _T, $($T),*> QueryFragment<_DB> for ConflictTarget<(_T, $($T),*)> where
                _DB: Backend + SupportsOnConflictClause,
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
                fn walk_ast(&self, mut out: AstPass<_DB>) -> QueryResult<()> {
                    out.push_sql(" (");
                    out.push_identifier(_T::NAME)?;
                    $(
                        out.push_sql(", ");
                        out.push_identifier($T::NAME)?;
                    )*
                    out.push_sql(")");
                    Ok(())
                }
            }

            impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
            }
        )*
    }
}

__diesel_for_each_tuple!(on_conflict_tuples);
<|endoftext|>


<commit_before>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

macro_rules! on_conflict_tuples {
    ($(
        $Tuple:tt {
            (0) -> A, SA, TA,
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
        }
    )+) => {
        $(
            impl<_DB, _T, $($T),*> QueryFragment<_DB> for ConflictTarget<(_T, $($T),*)> where
                _DB: Backend + SupportsOnConflictClause,
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
                fn walk_ast(&self, mut out: AstPass<_DB>) -> QueryResult<()> {
                    out.push_sql(" (");
                    out.push_identifier(_T::NAME)?;
                    $(
                        out.push_sql(", ");
                        out.push_identifier($T::NAME)?;
                    )*
                    out.push_sql(")");
                    Ok(())
                }
            }

            impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
            }
        )*
    }
}

__diesel_for_each_tuple!(on_conflict_tuples);
<commit_msg>Allow tuples with one element in on conflict clauses<commit_after>use crate::backend::{Backend, SupportsOnConflictClause};
use crate::expression::SqlLiteral;
use crate::query_builder::*;
use crate::query_source::Column;
use crate::result::QueryResult;

#[doc(hidden)]
pub trait OnConflictTarget<Table> {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct NoConflictTarget;

impl<DB> QueryFragment<DB> for NoConflictTarget
where
    DB: Backend + SupportsOnConflictClause,
{
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Table> OnConflictTarget<Table> for NoConflictTarget {}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ConflictTarget<T>(pub T);

impl<DB, T> QueryFragment<DB> for ConflictTarget<T>
where
    DB: Backend + SupportsOnConflictClause,
    T: Column,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" (");
        out.push_identifier(T::NAME)?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T> OnConflictTarget<T::Table> for ConflictTarget<T> where T: Column {}

impl<DB, ST> QueryFragment<DB> for ConflictTarget<SqlLiteral<ST>>
where
    DB: Backend + SupportsOnConflictClause,
    SqlLiteral<ST>: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> {}

macro_rules! on_conflict_tuples {
    ($(
        $Tuple:tt {
            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
        }
    )+) => {
        $(
            impl<_DB, _T, $($T),*> QueryFragment<_DB> for ConflictTarget<(_T, $($T),*)> where
                _DB: Backend + SupportsOnConflictClause,
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
                fn walk_ast(&self, mut out: AstPass<_DB>) -> QueryResult<()> {
                    out.push_sql(" (");
                    out.push_identifier(_T::NAME)?;
                    $(
                        out.push_sql(", ");
                        out.push_identifier($T::NAME)?;
                    )*
                    out.push_sql(")");
                    Ok(())
                }
            }

            impl<_T, $($T),*> OnConflictTarget<_T::Table> for ConflictTarget<(_T, $($T),*)> where
                _T: Column,
                $($T: Column<Table=_T::Table>,)*
            {
            }
        )*
    }
}

__diesel_for_each_tuple!(on_conflict_tuples);
<|endoftext|>


<commit_before>// High-level bindings to Cairo.

use cairo::{CAIRO_STATUS_SUCCESS, cairo_format_t, cairo_status_t, cairo_surface_t, cairo_t};
use cairo::bindgen::{cairo_create, cairo_fill, cairo_image_surface_create};
use cairo::bindgen::{cairo_image_surface_get_data, cairo_image_surface_get_format};
use cairo::bindgen::{cairo_image_surface_get_height, cairo_image_surface_get_stride};
use cairo::bindgen::{cairo_image_surface_get_width, cairo_rectangle, cairo_set_line_width};
use cairo::bindgen::{cairo_set_source_rgb, cairo_stroke, cairo_surface_destroy};
use cairo::bindgen::{cairo_surface_reference, cairo_surface_write_to_png_stream};
use cast::reinterpret_cast;
use io::{BytesWriter, Writer};
use ptr::addr_of;
use result::{Err, Ok, Result};
use vec::raw::{buf_as_slice, from_buf};

// FIXME: We should have a hierarchy of surfaces, but this needs to wait on case classes.
pub struct ImageSurface {
    cairo_surface: *cairo_surface_t,

    drop {
        cairo_surface_destroy(self.cairo_surface);
    }
}

impl ImageSurface {
    fn width()  -> c_int    { cairo_image_surface_get_width(self.cairo_surface)  }
    fn height() -> c_int    { cairo_image_surface_get_height(self.cairo_surface) }
    fn stride() -> c_int    { cairo_image_surface_get_stride(self.cairo_surface) }
    fn format() -> c_int    { cairo_image_surface_get_format(self.cairo_surface) }

    // FIXME: This should not copy!
    pure fn data() -> ~[u8] unsafe {
        let buffer = cairo_image_surface_get_data(self.cairo_surface);
        return from_buf(buffer, (self.stride() * self.height()) as uint);
    }
}

// Should be private.
fn image_surface_from_cairo_surface(cairo_surface: *cairo_surface_t) -> ImageSurface {
    assert !cairo_surface.is_null();
    ImageSurface { cairo_surface: cairo_surface }
}

pub fn ImageSurface(format: cairo_format_t, width: c_int, height: c_int) -> ImageSurface {
    let cairo_surface = cairo_image_surface_create(format, width, height);
    if cairo_surface.is_null() {
        fail ~"couldn't create Cairo image surface";
    }
    return image_surface_from_cairo_surface(move cairo_surface);
}

impl ImageSurface {
    fn write_to_png_stream(buffer: &BytesWriter) -> Result<(),cairo_status_t> unsafe {
        extern fn write_fn(closure: *c_void, data: *c_uchar, len: c_uint)
                        -> cairo_status_t unsafe {
            let writer: *BytesWriter = reinterpret_cast(&closure);
            do buf_as_slice(data, len as uint) |bytes| {
                (*writer).write(bytes);
            }
            return CAIRO_STATUS_SUCCESS;
        }

        let buffer_ptr = reinterpret_cast(&buffer);
        let status = cairo_surface_write_to_png_stream(self.cairo_surface, write_fn, buffer_ptr);
        if status != CAIRO_STATUS_SUCCESS {
            return Err(status);
        }

        return Ok(());
    }

    pure fn clone() -> ImageSurface {
        unsafe {
            cairo_surface_reference(self.cairo_surface);
            return image_surface_from_cairo_surface(self.cairo_surface);
        }
    }
}

struct Context {
    cairo_context: *cairo_t,
}

impl Context {
    fn set_line_width(width: c_double) {
        cairo_set_line_width(self.cairo_context, width);
    }

    fn set_source_rgb(r: c_double, g: c_double, b: c_double) {
        cairo_set_source_rgb(self.cairo_context, r, g, b);
    }

    fn rectangle(x: c_double, y: c_double, width: c_double, height: c_double) {
        cairo_rectangle(self.cairo_context, x, y, width, height);
    }

    fn stroke() {
        cairo_stroke(self.cairo_context);
    }

    fn fill() {
        cairo_fill(self.cairo_context);
    }
}

fn make_context(surface: &ImageSurface) -> Context {
    Context {
        cairo_context: cairo_create(surface.cairo_surface)
    }
}
<commit_msg>Update for library changes<commit_after>// High-level bindings to Cairo.

use cairo::{CAIRO_STATUS_SUCCESS, cairo_format_t, cairo_status_t, cairo_surface_t, cairo_t};
use cairo::bindgen::{cairo_create, cairo_fill, cairo_image_surface_create};
use cairo::bindgen::{cairo_image_surface_get_data, cairo_image_surface_get_format};
use cairo::bindgen::{cairo_image_surface_get_height, cairo_image_surface_get_stride};
use cairo::bindgen::{cairo_image_surface_get_width, cairo_rectangle, cairo_set_line_width};
use cairo::bindgen::{cairo_set_source_rgb, cairo_stroke, cairo_surface_destroy};
use cairo::bindgen::{cairo_surface_reference, cairo_surface_write_to_png_stream};
use cast::reinterpret_cast;
use io::{BytesWriter, Writer};
use ptr::addr_of;
use result::{Err, Ok, Result};
use vec::raw::{buf_as_slice, from_buf_raw};

// FIXME: We should have a hierarchy of surfaces, but this needs to wait on case classes.
pub struct ImageSurface {
    cairo_surface: *cairo_surface_t,

    drop {
        cairo_surface_destroy(self.cairo_surface);
    }
}

impl ImageSurface {
    fn width()  -> c_int    { cairo_image_surface_get_width(self.cairo_surface)  }
    fn height() -> c_int    { cairo_image_surface_get_height(self.cairo_surface) }
    fn stride() -> c_int    { cairo_image_surface_get_stride(self.cairo_surface) }
    fn format() -> c_int    { cairo_image_surface_get_format(self.cairo_surface) }

    // FIXME: This should not copy!
    pure fn data() -> ~[u8] unsafe {
        let buffer = cairo_image_surface_get_data(self.cairo_surface);
        return from_buf_raw(buffer, (self.stride() * self.height()) as uint);
    }
}

// Should be private.
fn image_surface_from_cairo_surface(cairo_surface: *cairo_surface_t) -> ImageSurface {
    assert !cairo_surface.is_null();
    ImageSurface { cairo_surface: cairo_surface }
}

pub fn ImageSurface(format: cairo_format_t, width: c_int, height: c_int) -> ImageSurface {
    let cairo_surface = cairo_image_surface_create(format, width, height);
    if cairo_surface.is_null() {
        fail ~"couldn't create Cairo image surface";
    }
    return image_surface_from_cairo_surface(move cairo_surface);
}

impl ImageSurface {
    fn write_to_png_stream(buffer: &BytesWriter) -> Result<(),cairo_status_t> unsafe {
        extern fn write_fn(closure: *c_void, data: *c_uchar, len: c_uint)
                        -> cairo_status_t unsafe {
            let writer: *BytesWriter = reinterpret_cast(&closure);
            do buf_as_slice(data, len as uint) |bytes| {
                (*writer).write(bytes);
            }
            return CAIRO_STATUS_SUCCESS;
        }

        let buffer_ptr = reinterpret_cast(&buffer);
        let status = cairo_surface_write_to_png_stream(self.cairo_surface, write_fn, buffer_ptr);
        if status != CAIRO_STATUS_SUCCESS {
            return Err(status);
        }

        return Ok(());
    }

    pure fn clone() -> ImageSurface {
        unsafe {
            cairo_surface_reference(self.cairo_surface);
            return image_surface_from_cairo_surface(self.cairo_surface);
        }
    }
}

struct Context {
    cairo_context: *cairo_t,
}

impl Context {
    fn set_line_width(width: c_double) {
        cairo_set_line_width(self.cairo_context, width);
    }

    fn set_source_rgb(r: c_double, g: c_double, b: c_double) {
        cairo_set_source_rgb(self.cairo_context, r, g, b);
    }

    fn rectangle(x: c_double, y: c_double, width: c_double, height: c_double) {
        cairo_rectangle(self.cairo_context, x, y, width, height);
    }

    fn stroke() {
        cairo_stroke(self.cairo_context);
    }

    fn fill() {
        cairo_fill(self.cairo_context);
    }
}

fn make_context(surface: &ImageSurface) -> Context {
    Context {
        cairo_context: cairo_create(surface.cairo_surface)
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="nightly", feature(const_fn))]

#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;

lazy_static! {
    /// Documentation!
    pub static ref NUMBER: u32 = times_two(3);

    static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];

    /// More documentation!
    #[allow(unused_variables)]
    #[derive(Copy, Clone, Debug)]
    pub static ref STRING: String = "hello".to_string();

    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "abc");
        m.insert(1, "def");
        m.insert(2, "ghi");
        m
    };

    // This should not compile if the unsafe is removed.
    static ref UNSAFE: u32 = unsafe {
        std::mem::transmute::<i32, u32>(-1)
    };

    // This *should* triggger warn(dead_code) by design.
    static ref UNUSED: () = ();

}

fn times_two(n: u32) -> u32 {
    n * 2
}

#[test]
fn test_basic() {
    assert_eq!(&**STRING, "hello");
    assert_eq!(*NUMBER, 6);
    assert!(HASHMAP.get(&1).is_some());
    assert!(HASHMAP.get(&3).is_none());
    assert_eq!(&*ARRAY_BOXES, &[Box::new(1), Box::new(2), Box::new(3)]);
    assert_eq!(*UNSAFE, std::u32::MAX);
}

#[test]
fn test_repeat() {
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
}

#[test]
fn test_meta() {
    // this would not compile if STRING were not marked #[derive(Copy, Clone)]
    let copy_of_string = STRING;
    // just to make sure it was copied
    assert!(&STRING as *const _ != &copy_of_string as *const _);

    // this would not compile if STRING were not marked #[derive(Debug)]
    assert_eq!(format!("{:?}", STRING), "STRING { __private_field: () }".to_string());
}

mod visibility {
    lazy_static! {
        pub static ref FOO: Box<u32> = Box::new(0);
        static ref BAR: Box<u32> = Box::new(98);
    }

    #[test]
    fn sub_test() {
        assert_eq!(**FOO, 0);
        assert_eq!(**BAR, 98);
    }
}

#[test]
fn test_visibility() {
    assert_eq!(*visibility::FOO, Box::new(0));
}

// This should not cause a warning about a missing Copy implementation
lazy_static! {
    pub static ref VAR: i32 = { 0 };
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct X;
struct Once(X);
const ONCE_INIT: Once = Once(X);
static DATA: X = X;
static ONCE: X = X;
fn require_sync() -> X { X }
fn transmute() -> X { X }
fn __static_ref_initialize() -> X { X }
fn test(_: Vec<X>) -> X { X }

// All these names should not be shadowed
lazy_static! {
    static ref ITEM_NAME_TEST: X = {
        test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE,
                  require_sync(), transmute(),
                  // Except this, which will sadly be shadowed by internals:
                  // __static_ref_initialize()
                  ])
    };
}

#[test]
fn item_name_shadowing() {
    assert_eq!(*ITEM_NAME_TEST, X);
}
<commit_msg>Added some old uncommited test case<commit_after>#![cfg_attr(feature="nightly", feature(const_fn))]

#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;

lazy_static! {
    /// Documentation!
    pub static ref NUMBER: u32 = times_two(3);

    static ref ARRAY_BOXES: [Box<u32>; 3] = [Box::new(1), Box::new(2), Box::new(3)];

    /// More documentation!
    #[allow(unused_variables)]
    #[derive(Copy, Clone, Debug)]
    pub static ref STRING: String = "hello".to_string();

    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "abc");
        m.insert(1, "def");
        m.insert(2, "ghi");
        m
    };

    // This should not compile if the unsafe is removed.
    static ref UNSAFE: u32 = unsafe {
        std::mem::transmute::<i32, u32>(-1)
    };

    // This *should* triggger warn(dead_code) by design.
    static ref UNUSED: () = ();

}

lazy_static! {
    static ref S1: &'static str = "a";
    static ref S2: &'static str = "b";
}
lazy_static! {
    static ref S3: String = [*S1, *S2].join("");
}

#[test]
fn s3() {
    assert_eq!(&*S3, "ab");
}

fn times_two(n: u32) -> u32 {
    n * 2
}

#[test]
fn test_basic() {
    assert_eq!(&**STRING, "hello");
    assert_eq!(*NUMBER, 6);
    assert!(HASHMAP.get(&1).is_some());
    assert!(HASHMAP.get(&3).is_none());
    assert_eq!(&*ARRAY_BOXES, &[Box::new(1), Box::new(2), Box::new(3)]);
    assert_eq!(*UNSAFE, std::u32::MAX);
}

#[test]
fn test_repeat() {
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
    assert_eq!(*NUMBER, 6);
}

#[test]
fn test_meta() {
    // this would not compile if STRING were not marked #[derive(Copy, Clone)]
    let copy_of_string = STRING;
    // just to make sure it was copied
    assert!(&STRING as *const _ != &copy_of_string as *const _);

    // this would not compile if STRING were not marked #[derive(Debug)]
    assert_eq!(format!("{:?}", STRING), "STRING { __private_field: () }".to_string());
}

mod visibility {
    lazy_static! {
        pub static ref FOO: Box<u32> = Box::new(0);
        static ref BAR: Box<u32> = Box::new(98);
    }

    #[test]
    fn sub_test() {
        assert_eq!(**FOO, 0);
        assert_eq!(**BAR, 98);
    }
}

#[test]
fn test_visibility() {
    assert_eq!(*visibility::FOO, Box::new(0));
}

// This should not cause a warning about a missing Copy implementation
lazy_static! {
    pub static ref VAR: i32 = { 0 };
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct X;
struct Once(X);
const ONCE_INIT: Once = Once(X);
static DATA: X = X;
static ONCE: X = X;
fn require_sync() -> X { X }
fn transmute() -> X { X }
fn __static_ref_initialize() -> X { X }
fn test(_: Vec<X>) -> X { X }

// All these names should not be shadowed
lazy_static! {
    static ref ITEM_NAME_TEST: X = {
        test(vec![X, Once(X).0, ONCE_INIT.0, DATA, ONCE,
                  require_sync(), transmute(),
                  // Except this, which will sadly be shadowed by internals:
                  // __static_ref_initialize()
                  ])
    };
}

#[test]
fn item_name_shadowing() {
    assert_eq!(*ITEM_NAME_TEST, X);
}
<|endoftext|>


<commit_before>use std::{
    collections::{HashMap, HashSet},
    path::{Path, PathBuf},
};

use pulldown_cmark::{escape, Event, LinkType, Tag};
use regex::{Captures, Regex};
use tracing::{event, instrument, Level};
use url::Url;

use crate::config::ResolvedConfig;
use crate::process::RenderingInput;

pub struct RenderAdapter<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> {
    pub(crate) ctx: &'a mut ProcessorContext<'a, 'c>,
    pub(crate) iter: I,
    // Table of contents
    // level, title, slug
    toc: Vec<(usize, String, String)>,
    // Cache for header slugification
    slugs_cache: HashMap<String, usize>,
}

const TOC_START: &'static str = r#"

Table of contents

"#;

const TOC_END: &'static str = r#"

"#;

impl<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> RenderAdapter<'a, 'b, 'c, I> {
    pub fn new(iter: I, ctx: &'a mut ProcessorContext<'a, 'c>) -> Self {
        Self {
            iter,
            ctx,
            toc: Vec::new(),
            slugs_cache: HashMap::new(),
        }
    }

    // Converts a header title into a slug.
    fn header_slug(&mut self, title: &str) -> String {
        let fixed_up = title
            .to_lowercase()
            .replace(" ", "-")
            .replace(|c: char| !c.is_alphanumeric(), "");
        if self.slugs_cache.contains_key(&fixed_up) {
            self.slugs_cache
                .insert(fixed_up.clone(), self.slugs_cache[&fixed_up] + 1);
            format!("{}{}", fixed_up, self.slugs_cache[&fixed_up])
        } else {
            self.slugs_cache.insert(fixed_up.clone(), 0);
            format!("{}", fixed_up)
        }
    }

    /// Sets up header links so that the TOC can be generated.
    pub fn setup_header_links(&mut self, inp: &str) -> String {
        let r = Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap();
        r.replace_all(inp, |caps: &Captures| {
            let level = caps[1]
                .parse::<usize>()
                .expect("Only numbers can be parsed here");
            let text = &caps[2];
            let slug = self.header_slug(&text);
            self.toc.push((level, text.to_string(), slug.clone()));
            format!(r#"<h{0} id="{1}">{2}</h{0}>"#, level, slug, text)
        })
        .into_owned()
    }

    /// Renders the table of contents
    /// and adds "toc" to the styles if necessary
    pub fn render_toc(&mut self) -> String {
        if self.toc.is_empty() {
            return String::new();
        }
        self.ctx.styles.insert("toc");
        self.ctx.styles.insert("link");
        let mut s = String::new();
        s.push_str(TOC_START);
        let mut last_level = 0;
        for (level, title, slug) in std::mem::take(&mut self.toc) {
            if level > last_level {
                s.push_str("
");
            }
            if level < last_level {
                s.push_str("
");
            }
            let escaped_slug = {
                let mut escaped = String::new();
                escape::escape_href(&mut escaped, &slug).unwrap();
                escaped
            };
            let escaped_title = {
                let mut escaped = String::new();
                escape::escape_html(&mut escaped, &title).unwrap();
                escaped
            };
            s.push_str(&format!(
                "
{}
",
                escaped_slug, escaped_title
            ));
            last_level = level;
        }
        s.push_str(TOC_END);
        s
    }
}

impl<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> Iterator for RenderAdapter<'a, 'b, 'c, I> {
    type Item = Event<'b>;

    #[instrument(name = "process", skip(self))]
    fn next(&mut self) -> Option<Self::Item> {
        let mut item = self.iter.next()?;
        let styles = &mut self.ctx.styles;
        let new_stack = &mut *self.ctx.new_stack;
        let render_stack = &mut *self.ctx.render_stack;
        let finished = self.ctx.finished;
        let out_dir = &self.ctx.config.roots.output;
        let base_dir = &self.ctx.config.roots.source;
        let filename = self.ctx.filename;
        if let Event::Start(Tag::Image(..)) = item {
            styles.insert("image");
        }
        if let Event::Start(Tag::Image(LinkType::Inline, ref mut url, _)) = item {
            if let Ok(parsed) = Url::parse(&url) {
                use sha2::Digest;
                let hashname = format!("{:x}", sha2::Sha256::digest(parsed.as_str().as_bytes()));
                let new_url = format!("/images/{}.webp", hashname);
                let input = RenderingInput::Image {
                    input: parsed,
                    output: hashname,
                };
                if !render_stack.contains(&input) && !finished.contains(&input) {
                    render_stack.insert(input.clone());
                    new_stack.push(input);
                }
                *url = new_url.into();
            }
        }
        if let Event::Start(Tag::Paragraph) = item {
            styles.insert("paragraph");
        }
        if let Event::Start(Tag::Heading(level)) = item {
            match level {
                1 => {
                    styles.insert("h1");
                }
                _ => {}
            }
        }
        if let Event::Start(Tag::Link(..)) = item {
            styles.insert("link");
        }
        if let Event::Start(Tag::Link(LinkType::Inline, ref mut url, _)) = item {
            if let Ok(parsed) = Url::parse(&url) {
                // check if scheme is hyperref, if so add to stack and rewrite url
                if parsed.scheme() == "hyperref" {
                    let parsed_path: &Path = parsed.path().as_ref();
                    let fname: PathBuf = if parsed_path.is_absolute() {
                        out_dir.join(parsed_path.strip_prefix("/").unwrap())
                    } else {
                        filename
                            .parent()
                            .unwrap_or("/".as_ref())
                            .join(parsed.path())
                    }
                    .with_extension("md");
                    #[cfg(target_os = "windows")]
                    // replace with backslashes so that \\?\ isn't broken
                    let fname: PathBuf = fname.to_str().unwrap().replace("/", "\\").into();
                    if let Ok(fname) = fname.canonicalize() {
                        let fname_for_url = fname.strip_prefix(&base_dir).unwrap();
                        #[cfg(target_os = "windows")]
                        // windows is dumb again
                        let fname_for_url: PathBuf =
                            fname_for_url.to_str().unwrap().replace("\\", "/").into();
                        // figure out new location
                        let new_location = format!(
                            "/{}",
                            fname_for_url.with_extension("html").to_str().unwrap(),
                        );
                        let input = RenderingInput::Page(fname);
                        if !render_stack.contains(&input) && !finished.contains(&input) {
                            match input {
                                RenderingInput::Page(ref fname) => {
                                    event!(Level::INFO, r#type = "walk", ?fname)
                                }
                                _ => {}
                            }
                            render_stack.insert(input.clone());
                            new_stack.push(input);
                        }
                        *url = new_location.into();
                    } else {
                        event!(Level::WARN, r#type = "invalid_hyperref", %url);
                    }
                }
            }
        }
        Some(item)
    }
}

/// Processing context for a single file
pub struct ProcessorContext<'a, 'b: 'a> {
    pub(crate) styles: &'a mut HashSet<&'b str>,
    pub(crate) filename: &'a Path,
    pub(crate) config: &'a ResolvedConfig,
    pub(crate) finished: &'a HashSet<RenderingInput>,
    pub(crate) render_stack: &'a mut HashSet<RenderingInput>,
    pub(crate) new_stack: &'a mut Vec<RenderingInput>,
}
<commit_msg>fix toc generation<commit_after>use std::{
    collections::{HashMap, HashSet},
    path::{Path, PathBuf},
};

use pulldown_cmark::{escape, Event, LinkType, Tag};
use regex::{Captures, Regex};
use tracing::{event, instrument, Level};
use url::Url;

use crate::config::ResolvedConfig;
use crate::process::RenderingInput;

pub struct RenderAdapter<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> {
    pub(crate) ctx: &'a mut ProcessorContext<'a, 'c>,
    pub(crate) iter: I,
    // Table of contents
    // level, title, slug
    toc: Vec<(usize, String, String)>,
    // Cache for header slugification
    slugs_cache: HashMap<String, usize>,
}

const TOC_START: &'static str = r#"

Table of contents

"#;

const TOC_END: &'static str = r#"

"#;

impl<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> RenderAdapter<'a, 'b, 'c, I> {
    pub fn new(iter: I, ctx: &'a mut ProcessorContext<'a, 'c>) -> Self {
        Self {
            iter,
            ctx,
            toc: Vec::new(),
            slugs_cache: HashMap::new(),
        }
    }

    // Converts a header title into a slug.
    fn header_slug(&mut self, title: &str) -> String {
        let fixed_up = title
            .to_lowercase()
            .replace(" ", "-")
            .replace(|c: char| !c.is_alphanumeric(), "");
        if self.slugs_cache.contains_key(&fixed_up) {
            self.slugs_cache
                .insert(fixed_up.clone(), self.slugs_cache[&fixed_up] + 1);
            format!("{}{}", fixed_up, self.slugs_cache[&fixed_up])
        } else {
            self.slugs_cache.insert(fixed_up.clone(), 0);
            format!("{}", fixed_up)
        }
    }

    /// Sets up header links so that the TOC can be generated.
    pub fn setup_header_links(&mut self, inp: &str) -> String {
        let r = Regex::new(r"<h(\d)>(.*?)</h\d>").unwrap();
        r.replace_all(inp, |caps: &Captures| {
            let level = caps[1]
                .parse::<usize>()
                .expect("Only numbers can be parsed here");
            let text = &caps[2];
            let slug = self.header_slug(&text);
            self.toc.push((level, text.to_string(), slug.clone()));
            format!(r#"<h{0} id="{1}">{2}</h{0}>"#, level, slug, text)
        })
        .into_owned()
    }

    /// Renders the table of contents
    /// and adds "toc" to the styles if necessary
    pub fn render_toc(&mut self) -> String {
        if self.toc.is_empty() {
            return String::new();
        }
        self.ctx.styles.insert("toc");
        self.ctx.styles.insert("link");
        let mut s = String::new();
        s.push_str(TOC_START);
        let mut last_level = 0;
        for (level, title, slug) in std::mem::take(&mut self.toc) {
            if level > last_level {
                s.push_str("
");
            }
            if level < last_level {
                s.push_str("
");
            }
            let escaped_slug = {
                let mut escaped = String::new();
                escape::escape_href(&mut escaped, &slug).unwrap();
                escaped
            };
            let escaped_title = {
                let mut escaped = String::new();
                escape::escape_html(&mut escaped, &title).unwrap();
                escaped
            };
            s.push_str(&format!(
                "
{}
",
                escaped_slug, escaped_title
            ));
            last_level = level;
        }
        for _ in 0..last_level {
            s.push_str("
");
        }
        s.push_str(TOC_END);
        s
    }
}

impl<'a, 'b, 'c: 'a, I: Iterator<Item = Event<'b>>> Iterator for RenderAdapter<'a, 'b, 'c, I> {
    type Item = Event<'b>;

    #[instrument(name = "process", skip(self))]
    fn next(&mut self) -> Option<Self::Item> {
        let mut item = self.iter.next()?;
        let styles = &mut self.ctx.styles;
        let new_stack = &mut *self.ctx.new_stack;
        let render_stack = &mut *self.ctx.render_stack;
        let finished = self.ctx.finished;
        let out_dir = &self.ctx.config.roots.output;
        let base_dir = &self.ctx.config.roots.source;
        let filename = self.ctx.filename;
        if let Event::Start(Tag::Image(..)) = item {
            styles.insert("image");
        }
        if let Event::Start(Tag::Image(LinkType::Inline, ref mut url, _)) = item {
            if let Ok(parsed) = Url::parse(&url) {
                use sha2::Digest;
                let hashname = format!("{:x}", sha2::Sha256::digest(parsed.as_str().as_bytes()));
                let new_url = format!("/images/{}.webp", hashname);
                let input = RenderingInput::Image {
                    input: parsed,
                    output: hashname,
                };
                if !render_stack.contains(&input) && !finished.contains(&input) {
                    render_stack.insert(input.clone());
                    new_stack.push(input);
                }
                *url = new_url.into();
            }
        }
        if let Event::Start(Tag::Paragraph) = item {
            styles.insert("paragraph");
        }
        if let Event::Start(Tag::Heading(level)) = item {
            match level {
                1 => {
                    styles.insert("h1");
                }
                _ => {}
            }
        }
        if let Event::Start(Tag::Link(..)) = item {
            styles.insert("link");
        }
        if let Event::Start(Tag::Link(LinkType::Inline, ref mut url, _)) = item {
            if let Ok(parsed) = Url::parse(&url) {
                // check if scheme is hyperref, if so add to stack and rewrite url
                if parsed.scheme() == "hyperref" {
                    let parsed_path: &Path = parsed.path().as_ref();
                    let fname: PathBuf = if parsed_path.is_absolute() {
                        out_dir.join(parsed_path.strip_prefix("/").unwrap())
                    } else {
                        filename
                            .parent()
                            .unwrap_or("/".as_ref())
                            .join(parsed.path())
                    }
                    .with_extension("md");
                    #[cfg(target_os = "windows")]
                    // replace with backslashes so that \\?\ isn't broken
                    let fname: PathBuf = fname.to_str().unwrap().replace("/", "\\").into();
                    if let Ok(fname) = fname.canonicalize() {
                        let fname_for_url = fname.strip_prefix(&base_dir).unwrap();
                        #[cfg(target_os = "windows")]
                        // windows is dumb again
                        let fname_for_url: PathBuf =
                            fname_for_url.to_str().unwrap().replace("\\", "/").into();
                        // figure out new location
                        let new_location = format!(
                            "/{}",
                            fname_for_url.with_extension("html").to_str().unwrap(),
                        );
                        let input = RenderingInput::Page(fname);
                        if !render_stack.contains(&input) && !finished.contains(&input) {
                            match input {
                                RenderingInput::Page(ref fname) => {
                                    event!(Level::INFO, r#type = "walk", ?fname)
                                }
                                _ => {}
                            }
                            render_stack.insert(input.clone());
                            new_stack.push(input);
                        }
                        *url = new_location.into();
                    } else {
                        event!(Level::WARN, r#type = "invalid_hyperref", %url);
                    }
                }
            }
        }
        Some(item)
    }
}

/// Processing context for a single file
pub struct ProcessorContext<'a, 'b: 'a> {
    pub(crate) styles: &'a mut HashSet<&'b str>,
    pub(crate) filename: &'a Path,
    pub(crate) config: &'a ResolvedConfig,
    pub(crate) finished: &'a HashSet<RenderingInput>,
    pub(crate) render_stack: &'a mut HashSet<RenderingInput>,
    pub(crate) new_stack: &'a mut Vec<RenderingInput>,
}
<|endoftext|>


<commit_before>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use sys_util::EventFd;

use BusDevice;

/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
pub struct I8042Device {
    reset_evt: EventFd,
}

impl I8042Device {
    /// Constructs a i8042 device that will signal the given event when the guest requests it.
    pub fn new(reset_evt: EventFd) -> I8042Device {
        I8042Device { reset_evt: reset_evt }
    }
}

impl BusDevice for I8042Device {
    fn read(&mut self, offset: u64, data: &mut [u8]) {
        if data.len() == 1 && offset == 3 {
            data[0] = 0x0;
        }
    }

    fn write(&mut self, offset: u64, data: &[u8]) {
        if data.len() == 1 && data[0] == 0xfe && offset == 3 {
            if let Err(e) = self.reset_evt.write(1) {
                error!("failed to trigger i8042 reset event: {:?}", e);
            }
        }
    }
}
<commit_msg>crosvm: make port 0x61 return 0x20, preventing Guest kernel hang<commit_after>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use sys_util::EventFd;

use BusDevice;

/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
pub struct I8042Device {
    reset_evt: EventFd,
}

impl I8042Device {
    /// Constructs a i8042 device that will signal the given event when the guest requests it.
    pub fn new(reset_evt: EventFd) -> I8042Device {
        I8042Device { reset_evt: reset_evt }
    }
}

// i8042 device is mapped I/O address 0x61. We partially implement two 8-bit
// registers: port 0x61 (I8042_PORT_B_REG, offset 0 from base of 0x61), and
// port 0x64 (I8042_COMMAND_REG, offset 3 from base of 0x61).
impl BusDevice for I8042Device {
    fn read(&mut self, offset: u64, data: &mut [u8]) {
        if data.len() == 1 && offset == 3 {
            data[0] = 0x0;
        } else if data.len() == 1 && offset == 0 {
            // Like kvmtool, we return bit 5 set in I8042_PORT_B_REG to
            // avoid hang in pit_calibrate_tsc() in Linux kernel.
            data[0] = 0x20;
        }
    }

    fn write(&mut self, offset: u64, data: &[u8]) {
        if data.len() == 1 && data[0] == 0xfe && offset == 3 {
            if let Err(e) = self.reset_evt.write(1) {
                error!("failed to trigger i8042 reset event: {:?}", e);
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Hooks for for the RPC system.
//!
//! Roughly corresponds to capability.h in the C++ implementation.

use crate::{any_pointer, Error, MessageSize};
use crate::traits::{Pipelined, Owned};
use crate::private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook};

use std::future::{Future};
use std::pin::{Pin};
use std::marker::Unpin;
use std::task::Poll;
#[cfg(feature = "rpc_try")]
use std::ops::Try;

use std::marker::PhantomData;

/// A computation that might eventually resolve to a value of type `T` or to an error
///  of type `E`. Dropping the promise cancels the computation.
#[must_use = "futures do nothing unless polled"]
pub struct Promise<T, E> {
    inner: PromiseInner<T, E>,
}

enum PromiseInner<T, E> {
    Immediate(Result<T,E>),
    Deferred(Pin<Box<dyn Future<Output=std::result::Result<T,E>> + 'static>>),
    Empty,
}

// Allow Promise<T,E> to be Unpin, regardless of whether T and E are.
impl <T, E> Unpin for PromiseInner<T,E> {}

impl <T, E> Promise<T, E> {
    pub fn ok(value: T) -> Promise<T, E> {
        Promise { inner: PromiseInner::Immediate(Ok(value)) }
    }

    pub fn err(error: E) -> Promise<T, E> {
        Promise { inner: PromiseInner::Immediate(Err(error)) }
    }

    pub fn from_future<F>(f: F) -> Promise<T, E>
        where F: Future<Output=std::result::Result<T,E>> + 'static
    {
        Promise { inner: PromiseInner::Deferred(Box::pin(f)) }
    }
}

impl <T, E> Future for Promise<T, E>
{
    type Output = std::result::Result<T,E>;

    fn poll(self: Pin<&mut Self>, cx: &mut ::std::task::Context) -> Poll<Self::Output> {
        match self.get_mut().inner {
            PromiseInner::Empty => panic!("Promise polled after done."),
            ref mut imm @ PromiseInner::Immediate(_) => {
                match std::mem::replace(imm, PromiseInner::Empty) {
                    PromiseInner::Immediate(r) => Poll::Ready(r),
                    _ => unreachable!(),
                }
            }
            PromiseInner::Deferred(ref mut f) => f.as_mut().poll(cx),
        }
    }
}

#[cfg(feature = "rpc_try")]
impl<T> Try for Promise<T, crate::Error> {
    type Ok = T;
    type Error = crate::Error;

    fn into_result(mut self) -> Result<Self::Ok, Self::Error> {
        unimplemented!();
    }

    fn from_error(v: Self::Error) -> Self {
        Promise::err(v)
    }
    fn from_ok(v: Self::Ok) -> Self {
        Promise::ok(v)
    }
}

/// A promise for a result from a method call.
#[must_use]
pub struct RemotePromise<Results> where Results: Pipelined + for<'a> Owned<'a> + 'static {
    pub promise: Promise<Response<Results>, crate::Error>,
    pub pipeline: Results::Pipeline,
}

/// A response from a method call, as seen by the client.
pub struct Response<Results> {
    pub marker: PhantomData<Results>,
    pub hook: Box<dyn ResponseHook>,
}

impl <Results> Response<Results>
    where Results: Pipelined + for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn ResponseHook>) -> Response<Results> {
        Response { marker: PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> crate::Result<<Results as Owned<'a>>::Reader> {
        self.hook.get()?.get_as()
    }
}

/// A method call that has not been sent yet.
pub struct Request<Params, Results> {
    pub marker: PhantomData<(Params, Results)>,
    pub hook: Box<dyn RequestHook>
}

impl <Params, Results> Request<Params, Results>
    where Params: for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn RequestHook>) -> Request <Params, Results> {
        Request { hook: hook, marker: PhantomData }
    }

    pub fn get<'a>(&'a mut self) -> <Params as Owned<'a>>::Builder {
        self.hook.get().get_as().unwrap()
    }

    pub fn set(&mut self, from: <Params as Owned>::Reader) -> crate::Result<()> {
        self.hook.get().set_as(from)
    }
}

mod map {
    // map implementation borrowed from the futures-util crate.

    use std::marker::Unpin;
    use std::pin::Pin;
    use std::future::Future;
    use std::task::{Poll};

    /// Future for the `map` combinator, changing the type of a future.
    ///
    /// This is created by the `Future::map` method.
    #[derive(Debug)]
    #[must_use = "futures do nothing unless polled"]
    pub struct Map<Fut, F> {
        future: Fut,
        f: Option<F>,
    }

    impl<Fut, F> Map<Fut, F> {
        pub(super) fn new(future: Fut, f: F) -> Map<Fut, F> {
            Map { future, f: Some(f) }
        }
    }

    impl<Fut: Unpin, F> Unpin for Map<Fut, F> {}

    impl<Fut, F, T> Future for Map<Fut, F>
        where Fut: Future,
              F: FnOnce(Fut::Output) -> T,
              Fut: Unpin
    {
        type Output = T;

        fn poll(mut self: Pin<&mut Self>, lw: &mut ::std::task::Context) -> Poll<T> {
            match Pin::new(&mut self.future).poll(lw) {
                Poll::Pending => Poll::Pending,
                Poll::Ready(output) => {
                    let f = self.f.take()
                        .expect("Map must not be polled after it returned `Poll::Ready`");
                    Poll::Ready(f(output))
                }
            }
        }
    }
}

impl <Params, Results> Request <Params, Results>
where Results: Pipelined + for<'a> Owned<'a> + 'static + Unpin,
      <Results as Pipelined>::Pipeline: FromTypelessPipeline
{
    pub fn send(self) -> RemotePromise<Results> {
        let RemotePromise {promise, pipeline, ..} = self.hook.send();
        let typed_promise = Promise::from_future(
            self::map::Map::new(
                promise,
                |response: Result<Response<any_pointer::Owned>, Error> | -> Result<Response<Results>, Error> {
                    Ok(Response {hook: response?.hook,
                                 marker: PhantomData})
                }));
        RemotePromise { promise: typed_promise,
                        pipeline: FromTypelessPipeline::new(pipeline)
                      }
    }
}

/// The values of the parameters passed to a method call, as seen by the server.
pub struct Params<T> {
    pub marker: PhantomData<T>,
    pub hook: Box<dyn ParamsHook>,
}

impl <T> Params <T> {
    pub fn new(hook: Box<dyn ParamsHook>) -> Params<T> {
        Params { marker: PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> crate::Result<<T as Owned<'a>>::Reader>
        where T: Owned<'a>
    {
        Ok(self.hook.get()?.get_as()?)
    }
}

/// The return values of a method, written in-place by the method body.
pub struct Results<T> {
    pub marker: PhantomData<T>,
    pub hook: Box<dyn ResultsHook>,
}

impl <T> Results<T>
    where T: for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn ResultsHook>) -> Results<T> {
        Results { marker: PhantomData, hook: hook }
    }

    pub fn get<'a>(&'a mut self) -> <T as Owned<'a>>::Builder {
        self.hook.get().unwrap().get_as().unwrap()
    }

    pub fn set(&mut self, other: <T as Owned>::Reader) -> crate::Result<()>
    {
        self.hook.get().unwrap().set_as(other)
    }
}

pub trait FromTypelessPipeline {
    fn new (typeless: any_pointer::Pipeline) -> Self;
}

pub trait FromClientHook {
    fn new(hook: Box<dyn ClientHook>) -> Self;
}

/// An untyped client.
pub struct Client {
    pub hook: Box<dyn ClientHook>
}

impl Client {
    pub fn new(hook: Box<dyn ClientHook>) -> Client {
        Client { hook : hook }
    }

    pub fn new_call<Params, Results>(&self,
                                     interface_id : u64,
                                     method_id : u16,
                                     size_hint : Option<MessageSize>)
                                     -> Request<Params, Results> {
        let typeless = self.hook.new_call(interface_id, method_id, size_hint);
        Request { hook: typeless.hook, marker: PhantomData }
    }

    /// If the capability is actually only a promise, the returned promise resolves once the
    /// capability itself has resolved to its final destination (or propagates the exception if
    /// the capability promise is rejected).  This is mainly useful for error-checking in the case
    /// where no calls are being made.  There is no reason to wait for this before making calls; if
    /// the capability does not resolve, the call results will propagate the error.
    pub fn when_resolved(&self) -> Promise<(), Error> {
        self.hook.when_resolved()
    }
}

/// An untyped server.
pub trait Server {
    fn dispatch_call(&mut self, interface_id: u64, method_id: u16,
                     params: Params<any_pointer::Owned>,
                     results: Results<any_pointer::Owned>)
                     -> Promise<(), Error>;
}

<commit_msg>remove capnp::map::Map and use async/await instead<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Hooks for for the RPC system.
//!
//! Roughly corresponds to capability.h in the C++ implementation.

use crate::{any_pointer, Error, MessageSize};
use crate::traits::{Pipelined, Owned};
use crate::private::capability::{ClientHook, ParamsHook, RequestHook, ResponseHook, ResultsHook};

use std::future::{Future};
use std::pin::{Pin};
use std::marker::Unpin;
use std::task::Poll;
#[cfg(feature = "rpc_try")]
use std::ops::Try;

use std::marker::PhantomData;

/// A computation that might eventually resolve to a value of type `T` or to an error
///  of type `E`. Dropping the promise cancels the computation.
#[must_use = "futures do nothing unless polled"]
pub struct Promise<T, E> {
    inner: PromiseInner<T, E>,
}

enum PromiseInner<T, E> {
    Immediate(Result<T,E>),
    Deferred(Pin<Box<dyn Future<Output=std::result::Result<T,E>> + 'static>>),
    Empty,
}

// Allow Promise<T,E> to be Unpin, regardless of whether T and E are.
impl <T, E> Unpin for PromiseInner<T,E> {}

impl <T, E> Promise<T, E> {
    pub fn ok(value: T) -> Promise<T, E> {
        Promise { inner: PromiseInner::Immediate(Ok(value)) }
    }

    pub fn err(error: E) -> Promise<T, E> {
        Promise { inner: PromiseInner::Immediate(Err(error)) }
    }

    pub fn from_future<F>(f: F) -> Promise<T, E>
        where F: Future<Output=std::result::Result<T,E>> + 'static
    {
        Promise { inner: PromiseInner::Deferred(Box::pin(f)) }
    }
}

impl <T, E> Future for Promise<T, E>
{
    type Output = std::result::Result<T,E>;

    fn poll(self: Pin<&mut Self>, cx: &mut ::std::task::Context) -> Poll<Self::Output> {
        match self.get_mut().inner {
            PromiseInner::Empty => panic!("Promise polled after done."),
            ref mut imm @ PromiseInner::Immediate(_) => {
                match std::mem::replace(imm, PromiseInner::Empty) {
                    PromiseInner::Immediate(r) => Poll::Ready(r),
                    _ => unreachable!(),
                }
            }
            PromiseInner::Deferred(ref mut f) => f.as_mut().poll(cx),
        }
    }
}

#[cfg(feature = "rpc_try")]
impl<T> Try for Promise<T, crate::Error> {
    type Ok = T;
    type Error = crate::Error;

    fn into_result(mut self) -> Result<Self::Ok, Self::Error> {
        unimplemented!();
    }

    fn from_error(v: Self::Error) -> Self {
        Promise::err(v)
    }
    fn from_ok(v: Self::Ok) -> Self {
        Promise::ok(v)
    }
}

/// A promise for a result from a method call.
#[must_use]
pub struct RemotePromise<Results> where Results: Pipelined + for<'a> Owned<'a> + 'static {
    pub promise: Promise<Response<Results>, crate::Error>,
    pub pipeline: Results::Pipeline,
}

/// A response from a method call, as seen by the client.
pub struct Response<Results> {
    pub marker: PhantomData<Results>,
    pub hook: Box<dyn ResponseHook>,
}

impl <Results> Response<Results>
    where Results: Pipelined + for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn ResponseHook>) -> Response<Results> {
        Response { marker: PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> crate::Result<<Results as Owned<'a>>::Reader> {
        self.hook.get()?.get_as()
    }
}

/// A method call that has not been sent yet.
pub struct Request<Params, Results> {
    pub marker: PhantomData<(Params, Results)>,
    pub hook: Box<dyn RequestHook>
}

impl <Params, Results> Request<Params, Results>
    where Params: for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn RequestHook>) -> Request <Params, Results> {
        Request { hook: hook, marker: PhantomData }
    }

    pub fn get<'a>(&'a mut self) -> <Params as Owned<'a>>::Builder {
        self.hook.get().get_as().unwrap()
    }

    pub fn set(&mut self, from: <Params as Owned>::Reader) -> crate::Result<()> {
        self.hook.get().set_as(from)
    }
}

impl <Params, Results> Request <Params, Results>
where Results: Pipelined + for<'a> Owned<'a> + 'static + Unpin,
      <Results as Pipelined>::Pipeline: FromTypelessPipeline
{
    pub fn send(self) -> RemotePromise<Results> {
        let RemotePromise {promise, pipeline, ..} = self.hook.send();
        let typed_promise = Promise::from_future(
            async move {
                Ok(Response {hook: promise.await?.hook,
                             marker: PhantomData})
            });
        RemotePromise { promise: typed_promise,
                        pipeline: FromTypelessPipeline::new(pipeline)
                      }
    }
}

/// The values of the parameters passed to a method call, as seen by the server.
pub struct Params<T> {
    pub marker: PhantomData<T>,
    pub hook: Box<dyn ParamsHook>,
}

impl <T> Params <T> {
    pub fn new(hook: Box<dyn ParamsHook>) -> Params<T> {
        Params { marker: PhantomData, hook: hook }
    }
    pub fn get<'a>(&'a self) -> crate::Result<<T as Owned<'a>>::Reader>
        where T: Owned<'a>
    {
        Ok(self.hook.get()?.get_as()?)
    }
}

/// The return values of a method, written in-place by the method body.
pub struct Results<T> {
    pub marker: PhantomData<T>,
    pub hook: Box<dyn ResultsHook>,
}

impl <T> Results<T>
    where T: for<'a> Owned<'a>
{
    pub fn new(hook: Box<dyn ResultsHook>) -> Results<T> {
        Results { marker: PhantomData, hook: hook }
    }

    pub fn get<'a>(&'a mut self) -> <T as Owned<'a>>::Builder {
        self.hook.get().unwrap().get_as().unwrap()
    }

    pub fn set(&mut self, other: <T as Owned>::Reader) -> crate::Result<()>
    {
        self.hook.get().unwrap().set_as(other)
    }
}

pub trait FromTypelessPipeline {
    fn new (typeless: any_pointer::Pipeline) -> Self;
}

pub trait FromClientHook {
    fn new(hook: Box<dyn ClientHook>) -> Self;
}

/// An untyped client.
pub struct Client {
    pub hook: Box<dyn ClientHook>
}

impl Client {
    pub fn new(hook: Box<dyn ClientHook>) -> Client {
        Client { hook : hook }
    }

    pub fn new_call<Params, Results>(&self,
                                     interface_id : u64,
                                     method_id : u16,
                                     size_hint : Option<MessageSize>)
                                     -> Request<Params, Results> {
        let typeless = self.hook.new_call(interface_id, method_id, size_hint);
        Request { hook: typeless.hook, marker: PhantomData }
    }

    /// If the capability is actually only a promise, the returned promise resolves once the
    /// capability itself has resolved to its final destination (or propagates the exception if
    /// the capability promise is rejected).  This is mainly useful for error-checking in the case
    /// where no calls are being made.  There is no reason to wait for this before making calls; if
    /// the capability does not resolve, the call results will propagate the error.
    pub fn when_resolved(&self) -> Promise<(), Error> {
        self.hook.when_resolved()
    }
}

/// An untyped server.
pub trait Server {
    fn dispatch_call(&mut self, interface_id: u64, method_id: u16,
                     params: Params<any_pointer::Owned>,
                     results: Results<any_pointer::Owned>)
                     -> Promise<(), Error>;
}

<|endoftext|>


<commit_before>use rustc::{declare_lint, hir, lint, lint_array};
use crate::utils;
use std::fmt;

/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an
/// `isize`.
///
/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric
/// cast by using the `add` method instead.
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// let vec = vec![b'a', b'b', b'c'];
/// let ptr = vec.as_ptr();
/// let offset = 1_usize;
///
/// unsafe { ptr.offset(offset as isize); }
/// ```
///
/// Could be written:
///
/// ```rust
/// let vec = vec![b'a', b'b', b'c'];
/// let ptr = vec.as_ptr();
/// let offset = 1_usize;
///
/// unsafe { ptr.add(offset); }
/// ```
declare_clippy_lint! {
    pub PTR_OFFSET_WITH_CAST,
    complexity,
    "uneeded pointer offset cast"
}

#[derive(Copy, Clone, Debug)]
pub struct Pass;

impl lint::LintPass for Pass {
    fn get_lints(&self) -> lint::LintArray {
        lint_array!(PTR_OFFSET_WITH_CAST)
    }
}

impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &lint::LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
        // Check if the expressions is a ptr.offset or ptr.wrapping_offset method call
        let (receiver_expr, arg_expr, method) = match expr_as_ptr_offset_call(cx, expr) {
            Some(call_arg) => call_arg,
            None => return,
        };

        // Check if the argument to the method call is a cast from usize
        let cast_lhs_expr = match expr_as_cast_from_usize(cx, arg_expr) {
            Some(cast_lhs_expr) => cast_lhs_expr,
            None => return,
        };

        let msg = format!("use of `{}` with a `usize` casted to an `isize`", method);
        if let Some(sugg) = build_suggestion(cx, method, receiver_expr, cast_lhs_expr) {
            utils::span_lint_and_sugg(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg, "try", sugg);
        } else {
            utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg);
        }

    }
}

// If the given expression is a cast from a usize, return the lhs of the cast
fn expr_as_cast_from_usize<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &'tcx hir::Expr,
) -> Option<&'tcx hir::Expr> {
    if let hir::ExprKind::Cast(ref cast_lhs_expr, _) = expr.node {
        if is_expr_ty_usize(cx, &cast_lhs_expr) {
            return Some(cast_lhs_expr);
        }
    }
    None
}

// If the given expression is a ptr::offset  or ptr::wrapping_offset method call, return the
// receiver, the arg of the method call, and the method.
fn expr_as_ptr_offset_call<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &'tcx hir::Expr,
) -> Option<(&'tcx hir::Expr, &'tcx hir::Expr, Method)> {
    if let hir::ExprKind::MethodCall(ref path_segment, _, ref args) = expr.node {
        if is_expr_ty_raw_ptr(cx, &args[0]) {
            if path_segment.ident.name == "offset" {
                return Some((&args[0], &args[1], Method::Offset));
            }
            if path_segment.ident.name == "wrapping_offset" {
                return Some((&args[0], &args[1], Method::WrappingOffset));
            }
        }
    }
    None
}

// Is the type of the expression a usize?
fn is_expr_ty_usize<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &hir::Expr,
) -> bool {
    cx.tables.expr_ty(expr) == cx.tcx.types.usize
}

// Is the type of the expression a raw pointer?
fn is_expr_ty_raw_ptr<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &hir::Expr,
) -> bool {
    cx.tables.expr_ty(expr).is_unsafe_ptr()
}

fn build_suggestion<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    method: Method,
    receiver_expr: &hir::Expr,
    cast_lhs_expr: &hir::Expr,
) -> Option<String> {
    let receiver = utils::snippet_opt(cx, receiver_expr.span)?;
    let cast_lhs = utils::snippet_opt(cx, cast_lhs_expr.span)?;
    Some(format!("{}.{}({})", receiver, method.suggestion(), cast_lhs))
}

enum Method {
    Offset,
    WrappingOffset,
}

impl Method {
    fn suggestion(&self) -> &'static str {
        match *self {
            Method::Offset => "add",
            Method::WrappingOffset => "wrapping_add",
        }
    }
}

impl fmt::Display for Method {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            Method::Offset => write!(f, "offset"),
            Method::WrappingOffset => write!(f, "wrapping_offset"),
        }
    }
}<commit_msg>eof newline<commit_after>use rustc::{declare_lint, hir, lint, lint_array};
use crate::utils;
use std::fmt;

/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an
/// `isize`.
///
/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric
/// cast by using the `add` method instead.
///
/// **Known problems:** None
///
/// **Example:**
/// ```rust
/// let vec = vec![b'a', b'b', b'c'];
/// let ptr = vec.as_ptr();
/// let offset = 1_usize;
///
/// unsafe { ptr.offset(offset as isize); }
/// ```
///
/// Could be written:
///
/// ```rust
/// let vec = vec![b'a', b'b', b'c'];
/// let ptr = vec.as_ptr();
/// let offset = 1_usize;
///
/// unsafe { ptr.add(offset); }
/// ```
declare_clippy_lint! {
    pub PTR_OFFSET_WITH_CAST,
    complexity,
    "uneeded pointer offset cast"
}

#[derive(Copy, Clone, Debug)]
pub struct Pass;

impl lint::LintPass for Pass {
    fn get_lints(&self) -> lint::LintArray {
        lint_array!(PTR_OFFSET_WITH_CAST)
    }
}

impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass {
    fn check_expr(&mut self, cx: &lint::LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
        // Check if the expressions is a ptr.offset or ptr.wrapping_offset method call
        let (receiver_expr, arg_expr, method) = match expr_as_ptr_offset_call(cx, expr) {
            Some(call_arg) => call_arg,
            None => return,
        };

        // Check if the argument to the method call is a cast from usize
        let cast_lhs_expr = match expr_as_cast_from_usize(cx, arg_expr) {
            Some(cast_lhs_expr) => cast_lhs_expr,
            None => return,
        };

        let msg = format!("use of `{}` with a `usize` casted to an `isize`", method);
        if let Some(sugg) = build_suggestion(cx, method, receiver_expr, cast_lhs_expr) {
            utils::span_lint_and_sugg(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg, "try", sugg);
        } else {
            utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg);
        }

    }
}

// If the given expression is a cast from a usize, return the lhs of the cast
fn expr_as_cast_from_usize<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &'tcx hir::Expr,
) -> Option<&'tcx hir::Expr> {
    if let hir::ExprKind::Cast(ref cast_lhs_expr, _) = expr.node {
        if is_expr_ty_usize(cx, &cast_lhs_expr) {
            return Some(cast_lhs_expr);
        }
    }
    None
}

// If the given expression is a ptr::offset  or ptr::wrapping_offset method call, return the
// receiver, the arg of the method call, and the method.
fn expr_as_ptr_offset_call<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &'tcx hir::Expr,
) -> Option<(&'tcx hir::Expr, &'tcx hir::Expr, Method)> {
    if let hir::ExprKind::MethodCall(ref path_segment, _, ref args) = expr.node {
        if is_expr_ty_raw_ptr(cx, &args[0]) {
            if path_segment.ident.name == "offset" {
                return Some((&args[0], &args[1], Method::Offset));
            }
            if path_segment.ident.name == "wrapping_offset" {
                return Some((&args[0], &args[1], Method::WrappingOffset));
            }
        }
    }
    None
}

// Is the type of the expression a usize?
fn is_expr_ty_usize<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &hir::Expr,
) -> bool {
    cx.tables.expr_ty(expr) == cx.tcx.types.usize
}

// Is the type of the expression a raw pointer?
fn is_expr_ty_raw_ptr<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    expr: &hir::Expr,
) -> bool {
    cx.tables.expr_ty(expr).is_unsafe_ptr()
}

fn build_suggestion<'a, 'tcx>(
    cx: &lint::LateContext<'a, 'tcx>,
    method: Method,
    receiver_expr: &hir::Expr,
    cast_lhs_expr: &hir::Expr,
) -> Option<String> {
    let receiver = utils::snippet_opt(cx, receiver_expr.span)?;
    let cast_lhs = utils::snippet_opt(cx, cast_lhs_expr.span)?;
    Some(format!("{}.{}({})", receiver, method.suggestion(), cast_lhs))
}

enum Method {
    Offset,
    WrappingOffset,
}

impl Method {
    fn suggestion(&self) -> &'static str {
        match *self {
            Method::Offset => "add",
            Method::WrappingOffset => "wrapping_add",
        }
    }
}

impl fmt::Display for Method {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            Method::Offset => write!(f, "offset"),
            Method::WrappingOffset => write!(f, "wrapping_offset"),
        }
    }
}
<|endoftext|>